Java Data Objects : objets de données Java.
Gérer la persistance d'objets Java de manière :
JDO vise à ajouter à des POJO une capacité de persistance de manière "orthogonale", c'est-à-dire sans contraintes pour ces objets (suivant en cela l'approche AOP, en ajoutant un aspect "persistance" aux objets).
En particulier il vise à garantir une indépendance :
JDO accède au support de stockage (datastore) via le moyen de son choix. Il peut s'agir de pilotes JDBC ou de connecteurs JCA dans le cas d'applications J2EE.
On peut distinguer 3 types de classes dans une application utilisant JDO :
Un objet JDO persistence-capable est un objet Java capable d'être :
Cette capacité lui est donnée après modification de son code (généralement son code compilé, ou bytecode) par outil. Cette instrumentation du code après compilation est appelée enhancement (enrichissement de code). Cet enhancement se base sur un descriptif des classes à rendre persistence-capable (définissant les classes et champs à rendre persistants, les champs caractérisant l'identité d'un objet, etc.), nommé métadonnées (metadata).
L'ensemble des états décrits ci-dessus (transactionnel-persistant, transactionnel-transitoire) est généralement qualifié d'ensembles des états "gérés" (managed), puisque c'est dans ces cas que la gestion JDO apporte une valeur ajoutée. Ceci dit un objet enhancé peut également passer en état transitoire-non transactionnel, c'est à dire ayant un comportement identique à des objets Java classiques ou JDO ne s'interpose plus.
Outre sa classe et les champs qui composent son état, un objet Persistence Capable est caractérisé par son identité qui peut être :
Les classes manipulant les objets persistence capable effectuent des :
Pour être géré (managed) par JDO, un objet doit implémenter un contrat de Persistence Capable via une instrumentation (enhancement) du bytecode de sa classe. Cette post-compilation ajoute au code des méthodes et champs additionnels, et du code statique permettant d'interragir avec l'infrastructure JDO (de tel ou tel fournisseur, l'enhancement étant standard et n'imposant donc pas de modification des classes métier si l'on change de fournisseur JDO).
Comme il s'agit de l'implémentation d'une interface, il est également possible - mais jamais fait en pratique - d'utiliser d'autres techniques que l'enhancement, telle que :
La correspondance (mapping) entre l'état mémoire de l'objet et son état persistant est rédigé dans un descripteur standard, externe au code (fichier XML), pouvant comporter des extensions propriétaires.
L'accès aux données peut être :
Transactionnel | Non transactionnel | ||
---|---|---|---|
Persistant | Lectures | ||
Transitoire | Comportement identique à celui d'un objet non JDO | ||
Optimisations | Ecriture dans le cache | <strong>NonTransactionalWrite</strong>=true |
|
Lecture non synchronisée | <strong>NonTransactionalRead</strong>=true |
||
Recherche dans le cache | <strong>ignoreCache</strong>=false |
Type | Description | |
---|---|---|
Optimisations | Conservation du cache après transaction | <strong>retainValues</strong>=true |
Non-restauration après annulation | <strong>restoreValue</strong>=false |
|
Ecriture dans le cache | <strong>NonTransactionalWrite</strong>=true |
|
Lecture non synchronisée | <strong>NonTransactionalRead</strong>=true |
|
Recherche dans le cache | <strong>ignoreCache</strong>=false |
Egalement le JDO Query Language (JDOQL) permet d'obtenir des instances ou collections d'instances JDO d'un type donné, éventuellement filtrées par divers critères exprimés dans une syntaxe proche de celle du langage Java.
Forme | Commentaire | ||
---|---|---|---|
Egalité | Avec contante | champ == valeur, champ != valeur, champ == null, champ != null | |
Entre champs | champ1 == champ2 | ||
Comparaison | Caractères | chaîne > valeur chaîne < valeur chaîne1 < chaîne2 chaîne1 > chaîne2 |
Pour les types non numérique, l'interprétation est dépendante de l'implémentation / du support de persistance |
chaîne.startsWith (valeur), chaîne.endsWith (valeur) | |||
Expression | expression1 && expression2 expression1 || expression2 |
||
Collections | Existence d'un élément caractérisé | collection.contains (var) && expression (var) | |
Vide | collection.isEmpty() |
Des contraintes peuvent également être imposées sur les ensembles résultats retournés, qui peuvent être :
L'API de JDO est définie dans le package
.
javax.jdo
On peut distinguer trois types de classes dans une application JDO :
PersistenceCapable
suite à leur post-compilation (enhancement).
Tout ou partie de leur champs (selon le mapping spécifié) sera alors pris en charge par JDO à l'exécution. Leur
identité peut être gérée par JDO de manière transparente (non durable ou datastore id) ou applicative et donc
explicite (application id). Dans ce dernier cas une classe d'identité applicative doit exister, semblable à celle
des EJB (combinaison publique, unique et sérialisable de champs de l'objet, avec constructeur par défaut, equals()
et hashCode()
). PersistenceCapable
. Ces classes utilisent typiquement des
PersistenceManager
, aptes à exécuter des requêtes, démarrer/terminer des transactions, ou
changer l'état des objets JDO (persistant, transient, transactionnel, etc.). Les
PersistenceManager
sont obtenus via une PersistenceManagerFactory
.
Une implémentation JDO doit au moins supporter une des identités SGBD.
En dehors de l'API visible par les développeurs utilisant JDO, comment cela fonctionne-t-il "à l'intérieur" ?
A l'exécution, toute instance JDO "enhancée" référence un gestionnaire de son état
(
) qui communique avec le StateManager
pour gérer la
persistance.PersistenceManager
Le StateManager
, chargé de gérer le cycle de vie d'une (ou plusieurs) instances, considère plusieurs
états possibles dans la vie du d'un PersistenceCapable
:
pm.makeTransactional(pc)
pc.setXxx(v)
.pm.makePersistent(pc)
ou sur un autre pc référençant ce pc par exemple (persistance de proche en proche).
pc=getObjectById()
par exemple pc.setXxx(v)
par exemplepm.deletePersistent(pc)
par exemple.WHERE
, le support de
l'héritage, etc.default-fetch-group
) paramétrable, alors que les EJB ne le spécifient pas (généralement
l'ensemble des champs est chargé)myCollection.contains(var1) &&
var1.otherCollection.contains(var2) && var2 == xxx
par exemple), alors que EJB QL ne permet pas
de requêtes de ce type (field.collection.field
est interdit). Cependant depuis JDO 2.0 un certain
rapprochement entre ces deux langages a été décidé et JDO QL pourra être un langage utilisable dans EJB 3.0.
commit()
ou de rollback()
de transaction
(paramétrage propriétaire pour les EJB quand c'est possible)Du FUD a parfois été présenté sur JDO.
objet.getCollection().add(e)
ne devrait générer qu'une
insertion et ne pas charger la collection pour rien. Enfin, il est une autre vitesse où JDBC n'a pas non plus forcément l'avantage
: celle du développement. Les projets sont de plus en plus complexes (et
donc coûteux) et demandent plus d'abstraction pour obtenir des temps de développement -- et des possibilités
fonctionnelles -- acceptables. Allez donc implémenter en JDBC la requête JDO QL : manager.department.employees.contains
(anEmployee) && ((Woman) anEmployee).husband == this
par exemple. JDO saura le faire de la
manière la plus optimisée possible, sans que le développeur perde du temps à descendre au niveau du support de
persistance aux paradigme, API et specificités différentes du niveau applicatif. Logiciel | Standard JDO | Commentaire | |||||
---|---|---|---|---|---|---|---|
Version | 1 | 2 | |||||
Release | 0 | 0 | |||||
Domaine | Technologie | Maintenance | 0 | 1 | |||
Inclus dans | J2EE | Package optionnel, intégrable via JCA. | |||||
Requêtes | JDOQL | Oui | JDO Query Language | ||||
Appel de fonctions | Traitement sur le résultat (collection.size() , etc.) ou Query en
langage SQL
|
query.setResult (min ou max ou sum ou avg ou manipulation de chaînes) | |||||
Appel de méthodes | Non | object1.compute() > objet2.getMax() | |||||
Transactions | Distribuées | Oui | |||||
Optimistes | Optionnel | JDOOptimisticVerificationException |
|||||
Déconnectées | Non | Oui | Travail sur des instances détachées (client distant) puis reconnection. | ||||
Ecriture non transactionnelle | Optionnel | ||||||
Lecture non transactionnelle | Optionnel | ||||||
Environnement | géré | Oui | |||||
non-géré | Oui | ||||||
Stockage | SGBDR | mapping via extensions des métadonnées JDO | mapping normalisé | Oracle, MySQL, etc. | |||
SGBDO | Oui | Versant par exemple | |||||
Non persistant | Optionnel | Transactions en mémoire | |||||
Instance | Identité | Durable | Datastore | Oui | Fournie par l'implémentation JDO, masquée dans l'objet | ||
Applicative | Composée | Composée ou simple | |||||
Non durable | Optionnel | ||||||
Changement | Optionnel | ||||||
Transactionnelles | Transitoire | Optionnel | |||||
Persistante | Oui | ||||||
Non transactionnelles | Transitoire | Oui | |||||
Persistante | Optionnel | ||||||
Types | Simples | Booléens | boolean java.lang.Boolean |
||||
Entiers | byte short int long java.lang.Byte java.lang.Short java.lang.Integer
java.lang.Long java.math.BigInteger |
||||||
Flottants | float double java.lang.Float java.lang.Double java.math.BigDecimal
|
||||||
Objet | java.lang.Object et dérivés |
null supporté |
|||||
Chaîne | java.lang.String char java.lang.Character |
||||||
Internationalisation | java.util.Locale |
||||||
Date | java.util.Date |
||||||
Tableaux | Primitifs | boolean[] byte[] short[] int[] long[] char[] float[] double[] |
|||||
Array | Optionnel | ||||||
Dictionnaires | Map | Optionnel | |||||
HashSet | Oui | ||||||
HashMap | Optionnel | ||||||
TreeMap | Optionnel | ||||||
Hashtable | Optionnel | ||||||
Collections | Collection | Optionnel | |||||
Listes | List | Optionnel | |||||
ArrayList | Optionnel | ||||||
LinkedList | Optionnel | ||||||
Vector | Optionnel | ||||||
Ensembles | Set | Optionnel | |||||
TreeSet | Optionnel | ||||||
Bidirectionnelles | Non spécifié | Oui | |||||
Supression en cascade | Non spécifié | Oui | Cascade delete |
Un exemple de classe persistante est n'importe quelle classe POJO.
Un exemple de code JDO est :
import javax.jdo.*;
// Code code suppose que pm réference un PersistenceManager et qu'il y a un contexte transactionnel en cours
Employee jerome = new Employee ("Jérôme", "Beau");
Address jeromeAddress = new Address("71 rue Desnouettes", "75015", "Paris");
jerome.setAddress (jeromeAddress);
Transaction tx = pm.currentTransaction();
tx.begin();
{
ProjectId lidoProjectId = new ProjectId ("LiDO", 3.1); // Identifiant métier du projet
Project lidoProject = pm.getObjectById (lidoProjectId, true); // Récupère le projet en base
jerome.getProjects().add (lidoProject);
lidoProject.getWorkers().add (jerome);
pm.makePersistent (jerome);
// Rend aussi jeromeAddress persistant, de proche en proche (clôture transitive)
}
tx.commit(); // Ecrit les jerome et jeromeAddress en base
tx.begin();
{
// Récupère les projets dont le nom commence par "L", dont les collaborateurs et travaillent à Paris ou qui contiennent le collaborateur jerome
Query query = pm.newQuery (Projet.class, "workers.contains(aPeople) && aPeople.address.city == someCity && name.startsWith(\"L\") || aPeople == somePeople");
myQuery.declareVariables ("Employee aPeople");
myQuery.declareParameters ("String someCity, Employee somePeople");
myQuery.setOrdering ("name ascending, manager.name ascending"); // Trie les résultat par nom de projet puis éventuellement par nom du manager du projet
Collection foundProjects = (Collection) myQuery.execute (jerome, "Paris"); // Exécute la requête avec les arguments suivants
Iterator foundProjectsIterator = foundProjects.iterator();
while (iter.hasNext()) {
Project aFoundProject = (Project) foundProjectsIterator.next();
// Utilise projet
}
myQuery.close (result);
}
tx.commit();
pm.close();
Un exemple de descripteur JDO standard est :
<!--?xml version="1.0" encoding="UTF-8"?-->
<!DOCTYPE jdo SYSTEM "jdo.dtd">
<jdo>
<package name="net.javarome.jdo.samples">
<class name="Person" identity-type="application" objectidclass="PersonKey">
<field name="nom" primary-key="true">
</field></class>
<class name="Employe" identity-type="application" persistence-capable-superclass="Person">
<field name="salaire" default-fetch-group="true">
<field name="dept">
<field name="chef">
</field></field></field></class>
<class name="Project" identity-type="application">
<field name="nom" primary-key="true">
<field name="workers">
<collection element-type="Employe">
</collection></field>
</field></class>
</package>
</jdo>
Fournisseur | Exadel | Object Frontier | OSS | Object Industries | Versant | Solarmetric | Xcalia (LIBeLIS) | ObjectDB Software | (Apache) Jakarta | SignSoft | (Apache) | |||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Produit | Exadel JDO | Frontier Suite for JDO | JPOX | JRelay | JDO Genie | Fast Objects | Kodo JDO | LiDO | ObjectDB | OJB | intelliBO | TJDO | ||||
Version | 3 | 1 | 2 | j2 | 2 | 3 | 3 | 2 | ||||||||
Domaine | Technologie | Release | 0 | 1 | 0 | 5 | 1 | 0 | ||||||||
Standard | JDO | Version | 1.0 | 1.0 | 2.0-- | 2.0-- | ||||||||||
Cache | Partagé / niveau 2 | Entre PM | Oui | Oui | Active Java Cache | Oui | lido.cache.mode=shared |
CacheConfiguration. setUseNTXCache (true) |
||||||||
Entre PMF | JMS ou TCP |
|
||||||||||||||
Agrafage d'objets | DataCache.pin(objectId) |
pin(object) ou lido.cache.classStrategy (myClassName)= pinned |
|
|||||||||||||
Par classe | Extension cache-strategy=yes|all d'une classe |
Extension can-cache =true d'une classe (défaut) |
Oui | CacheConfiguration. setUseNTXCache (false) |
||||||||||||
Distribué | Version entreprise | Oui | JMS | Via cache listeners plugins, JDOGenie Servers | Non | kodo.DataCache |
via DataRepository API | JMS, TCP | ||||||||
JCache | Non | Oui | via DataRepository API | |||||||||||||
Pluggable | Oui | Oui | ||||||||||||||
Tangosol | Oui | kodo.DataCache: tangosol(TangosolCacheName=kodo, TangosolCacheType=distributed) |
via DataRepository API | |||||||||||||
Exclusif | lido.cache.exclusive=true |
|||||||||||||||
Evénements | kodo.event.RemoteCommitProvider: jms ou tcp |
lido.cache.CommitListeners= com.acme.MyCommitListener |
||||||||||||||
Requêtes | JDO QL | Extensions | String | toLowerCase() |
stringContains() caseInsStarts() caseInsEnds() caseInsContains() |
toLowerCase() toUpperCase() |
Non | charAt() length() startsWith(substr,pos) substring(begin,end) toLowerCase()
toUpperCase() |
||||||||
Map | containsKey(key) <code>contains(value) isEmpty()</code> |
containsKey(key) containsValue(value) |
containsKey(key) containsValue(value) |
Non | ||||||||||||
Curseurs | Mono-transaction | randomAccess= true |
com.solarmetric.kodo. ResultListProperties |
cursor= basic |
||||||||||||
Cross-transactions | cursor= cross-pm |
|||||||||||||||
Taille paramétrable | fetch-size=n LIDOHINT |
|||||||||||||||
Cache des résultat | kodo.QueryCache: CacheSize=n |
Oui | ||||||||||||||
Chargement | Grappe | fetch-group=fields |
Eager Fetching Personnalisable Fetch groups |
load= dfg| true |
JDOQLQuery. addFetchGroupAttribute ("myAttribute"); |
|||||||||||
SQL | Libre | Oui | Oui | Non | sqlEmbed |
|
Non | SQLQuery query = QueryFactory. newSQLQuery() |
Oui | |||||||
Procédures stockées | query.setFilter ("call ...") |
|||||||||||||||
Transactions | Distribuées (XA) | Oui | Oui | Non | Oui | Oui | Oui | |||||||||
Optimistes | Versionnage | Oui | Oui | Oui | Oui | N° version, Ttimestamp | Non | Non | Extension jdbc-version-ind" value="version-number" |
champ JDO sélectionné (lido.optimistic.class.MyClass =selected sur champ int ou Date) |
Oui | Extension optimistic-lock (timestamp ou version ) |
||||
Champs modifiés | Oui | Tous, champs modifiés, champ / classe | Non | |||||||||||||
Ecriture non transactionnelle | Non | Non | Oui | Non | Non | Oui | Oui | Oui | ||||||||
Lecture non transactionnelle | Oui | Oui | Oui | Non | Non | Oui | Oui | Oui | ||||||||
Environnement | Intégration serveurs applicatifs | Weblogic, WebSphere, JBoss, Orbix E2A, Oracle 9i, HP AS, Orion, JRun | Java Connectors | Non | DataSource (Jboss, WebLogic, WenSphere, SunOne, JRun, Borland) |
Java Connectors | Java Connectors | |||||||||
Attacher/détacher (JDO 2.0) | Oui | Oui | ||||||||||||||
Stockage | SGBDR | CloudScape | Non | Oui | Non | Non | Non | Non | 4.0.6 | Oui | Non | Non | 4.0.6, 5.0.9 | |||
DB2 | 7.1 | Oui | 07.02.0000 | Oui | Non | Oui | 7.2 | Oui | Non | Oui | 7.2.3 | |||||
FireBird | Non | Non | Non | 1.0.2 | Non | Non | Non | Oui | Non | Non | 1.0.0.796 | |||||
HSQL DB | Non | Non | Non | Non | Non | Non | 1.6 | Oui | Non | Non | Non | |||||
Ingres | Non | Non | Non | Non | Non | Non | Non | Oui | Non | Non | Non | Non | ||||
Informix | Non | Oui | Non | 9 | Non | Non | Oui | Oui | Non | 7.31 | Non | |||||
InstantDB | Non | Non | Non | Non | Non | Non | 3.26 | Oui | Non | 3.14 | Non | |||||
Interbase | Non | Non | Non | 6 | Non | Non | Non | Oui | Non | Non | Oui | |||||
JDataStore | Non | Non | Non | Oui | ||||||||||||
MS Access | Non | Oui | Non | Non | Non | Non | Oui | Oui | Non | Non | Non | |||||
MS FoxPro | Non | Non | Oui | |||||||||||||
MS SQL Server | 8.0 | Oui | 7.0 | 7.0 | Non | Oui | 8.0 | Oui | Non | Oui | 7.0 SP4, 2000 SP2 | |||||
McKoi | Non | Non | Non | Non | Non | Non | Non | Oui | Non | Non | Non | |||||
MySQL | Non | Oui | Non | 3.23.49, 4.0.12 | Non | Non | 3.23 | Oui | Non | Oui | 3.23.55-max | |||||
Oracle | 8.1, 9.2 | Oui | 8.1.7 | 8.1.7 | Non | Oui | 8.1-9.1 | Oui | Non | 8.1.7 | 8.1.7.4.0 | |||||
Pervasive SQL | Non | Non | Non | Non | Non | Non | Non | Non | Non | Oui | Non | |||||
PointBase | Non | Oui | Non | 4.5 | Non | Non | 4.2 | Oui | Non | Non | Non | |||||
PostgreSQL | Non | Non | 7.1.3 | 7.3.1 | Non | Non | 7.2.1 | Oui | Non | Oui | 7.2.1, 7.3.1, 7.3.2-1 | |||||
Progress | Non | Non | Non | Non | Non | Non | Non | Non | Non | Oui | Non | |||||
SAP DB | Non | Non | Non | 7.3 | Non | Non | Non | Non | Oui | 7.4.3 Build 010-120-035-462 | ||||||
Sybase | Non | Oui | Non | 11.9.2, 12.5 | Non | Non | 12.5 | Oui | Non | Oui | Non | |||||
Unisys | Non | Non | Non | Non | Non | Non | Non | Oui | Non | Non | Non | Non | ||||
SGBDO | Versant | Non | Non | Non | Non | Non | Oui | Non | Oui | Oui | Non | Non | Oui | Non | ||
Autre | Propriétaire | Non | Non | Non | Non | FDB | ObjectDB | |||||||||
Autre | Via dictionnaire fourni | Non | ||||||||||||||
XML | Non | Non | Non | Non | Non | Oui | Non | Oui | ||||||||
Instance | Identité | Durable | Datastore | Oui | Oui | Oui | Oui | Oui | Oui | Oui | Oui | |||||
Applicative | Oui | Oui | Oui | Génération automatique de classe | Non | Non | Oui | Génération automatique de classe et de valeurs | Non | |||||||
Personnalisé | Oui | OidProvider | ||||||||||||||
SGBD | Champs identité, séquences, tables | |||||||||||||||
Non durable | Oui | Non | Non | Non | Non | Oui | Non | |||||||||
Changement | Non | Non | Non | Non | Non | Oui | Non | |||||||||
Transactionnelles | Transitoire | Oui | Oui | Oui | Oui | |||||||||||
Persistante | Oui | Oui | Oui | Oui | ||||||||||||
Non transactionnelles | Transitoire | Oui | Oui | Oui | ||||||||||||
Persistante | Oui | Oui | Oui | Oui | ||||||||||||
Détachement/attachement | Oui | |||||||||||||||
Collections | Nulles | Oui | Oui | Non | Non | Oui | Oui | Non | Oui | |||||||
Tableaux | Array[] | Non | Oui | Oui | Oui | Oui | Oui | Oui | Oui | Oui | Non | |||||
int[][], byte[][] | Oui | |||||||||||||||
int[][][], byte[][][] | Oui | |||||||||||||||
Dictionnaires | Map | Non | Non | Oui | Oui | Oui | Oui | Oui | Oui | Oui | Oui | |||||
HashSet | Oui | Oui | Oui | Oui | Oui | Oui | Oui | Oui | Non | Non | ||||||
HashMap | Non | Oui | Oui | Oui | Non | Oui | Oui | Oui | Oui | Non | ||||||
TreeMap | Non | Oui | Oui | Non | Non | Non | Oui | Oui | Oui | Non | ||||||
Hashtable | Non | Oui | Oui | Oui | Oui | Non | Oui | Oui | Oui | Non | ||||||
Listes | List | Oui | Oui | Oui | Oui | Oui | Oui | Oui | Oui | Oui | Non | |||||
ArrayList | Oui | Oui | Oui | Oui | Oui | Oui | Oui | Oui | Oui | Non | ||||||
LinkedList | Oui | Oui | Oui | Oui | Oui | Oui | Oui | Oui | Oui | Non | ||||||
Vector | Oui | Oui | Oui | Oui | Oui | Non | Oui | Oui | Oui | Non | ||||||
Ensembles | Set | Oui | Oui | Oui | Oui | Oui | Non | Oui | Oui | Oui | Oui | |||||
TreeSet | Oui | Oui | Oui | Non | Oui | Non | Oui | Non | Oui | Non | ||||||
Développement | Outils | Mapping graphique | Oui | Non | LiDO Studio | JDO Explorer | ||||||||||
Navigateur de modèle | Non | Navilis | ||||||||||||||
Génération de schéma | Oui | Oui | Oui | DefineSchema, LPM | schemagen |
|||||||||||
Retro- ingénierie de schéma | Oui | Pour XML | ClassGenerator | |||||||||||||
Evolution de schéma | Oui | DefineSchema | ||||||||||||||
Intégration IDE | JBuilder | Non | Non | 6 | Oui | Non | Oui | |||||||||
TCC | Non | Non | Non | Non | Lido 1.4 | Oui | ||||||||||
Sun ONE Studio | Non | Oui | Oui | Non | Non | |||||||||||
Eclipse / WSAD | Non | Oui | Non | Oui | 2.x (LiDO Studio) | Non | ||||||||||
API | Métadonnées | Oui | ||||||||||||||
Javadoc | XDocLet | JDODocLet | ||||||||||||||
Taglib | Non | Oui | ||||||||||||||
Suppressions en cascade | Non | Extension dependent du champ collection |
Extensions dependent , value-dependent , key-dependent et
element-dependent |
Automatique pour collections en reverse , sinon en partie via l'extension sql-delete-behavior
(sinon InstanceCallback)
|
Extension cascade-delete du champ |
|||||||||||
Mapping | Classe | Plusieurs tables | Non | Oui | Extension table du champ collection. Clés primaires différentes supportées |
Oui | ||||||||||
Héritage | Vertical | Oui | Non | Oui | <inheritance-strategy type="per-class" > |
Extension inheritance d'une classe |
||||||||||
Horizontal | Non | Non | Oui | <inheritance-strategy type="per-concrete-class" >
(défaut)
|
Non | |||||||||||
Autre | Possible | |||||||||||||||
Plat / Filtré | Non | Oui | Oui | Oui | <inheritance-strategy type="per-hierarchy"> |
Oui | ||||||||||
Relations | 1-1 | Oui | Oui | |||||||||||||
Inversée | Oui | |||||||||||||||
1-n | Table de liaison | Oui | Oui | Oui | Oui | Oui (défaut) | ||||||||||
Inversée (non ordonnée) | Extension inverse du champ collection |
Extension inverse du champ collection |
<associate field="f" to-column="c"> |
|||||||||||||
n-m | Table de liaison | Oui | Oui | Oui | Oui | Oui | ||||||||||
Inversée (non ordonnée) | Oui | Extension inverse du champ collection |
Oui | Non | ||||||||||||
Champs | Convertisseurs | Oui | JdbcConverter |
custom-mapping=ClassMapping , extension column-length |
CustomMapper, CustomizableMapper |
|||||||||||
DataStore | Multiples | Non | Extension datastore d'une classe |
Non | Non |