diff --git a/reference/en/modules/collection_mapping.xml b/reference/en/modules/collection_mapping.xml index 8e599cdaa6..c43235fae5 100644 --- a/reference/en/modules/collection_mapping.xml +++ b/reference/en/modules/collection_mapping.xml @@ -1,7 +1,7 @@ Collection Mapping - + Persistent Collections @@ -27,20 +27,25 @@ Now the caveat: persistent collections do not retain any extra semantics added by the class implementing the collection interface (eg. iteration order of a LinkedHashSet). - The persistent collections actually behave like + The Java type of a property holding a collection must be the interface type: Map, + Set, List, or simply Collection; never + HashMap, TreeSet or ArrayList. This + restriction exists because, when you're not looking, Hibernate sneakily replaces your instances + of Map, Set and List with instances + of its own persistent implementations of Map, Set, or + List. (So also be careful when using == on your collections.) + + + + You may therefore initialize a collection in your class with whatever implementation + you find compatible. The persistent collections injected by Hibernate behave like HashMap, HashSet, TreeMap, TreeSet and ArrayList - respectively. Furthermore, the Java type of a property holding a collection must be - the interface type (ie. Map, Set or - List; never HashMap, TreeSet or - ArrayList). This restriction exists because, when you're not looking, - Hibernate sneakily replaces your instances of Map, Set - and List with instances of its own persistent implementations of - Map, Set or List. (So also be careful - when using == on your collections.) + respectively. Of course, this depends on the mapping style you chose (ie. ordered or + not, preserving position of elements, allowing duplicates, etc). +kittens = cat.getKittens(); // Okay, kittens collection is a Set +(HashSet) cat.getKittens(); // Error!]]> - Collections obey the usual rules for value types: no shared - references, created and deleted along with containing entity. Due to the underlying + Collections (not the contents) obey the usual rules for value types: no shared + references, created and deleted along with the owning entity. Due to the underlying relational model, they do not support null value semantics; Hibernate does not distinguish between a null collection reference and an empty collection. @@ -73,36 +78,41 @@ kittens = cat.getKittens(); //Okay, kittens collection is a Set Collection instances are distinguished in the database by a foreign key to the owning entity. This foreign key is referred to as the - collection key . The collection key is mapped by - the <key> element. If you have a foreign-key constraint - set in the database, and have chosen the ON DELETE CASCADE - option, always use the on-delete attribute on your - <key> mappings: + collection key , on the table holding the collection elements. + The collection key is mapped by the <key> element. If you + have a foreign-key constraint set in the database, and have chosen the + ON DELETE CASCADE option, always use the + on-delete attribute on your <key> + mappings: ]]> Collections may contain almost any other Hibernate type, including all basic types, - custom types, entity types and components. This is an important definition: An object - in a collection can either be handled with "pass by value" semantics (it therefore - fully depends on the collection owner) or it can be a reference to another entity - with an own lifecycle. Collections may not contain other collections. The contained type + custom types, components, and of course, references to other entities. This is an + important definition: An object in a collection can either be handled with "pass by + value" semantics (it therefore fully depends on the collection owner) or it can be a + reference to another entity, with its own lifecycle. In this case, only the "link" + between two objects is stored in the collection (non-Java developers call these links + "pointers"). Collections may not contain other collections. The contained type is referred to as the collection element type. Collection elements are mapped by <element>, <composite-element>, - <one-to-many>, <many-to-many> or - <many-to-any>. The first two map elements with value semantics, - the other three are used to map entity associations. + or in the case of entity references, with <one-to-many>, + <many-to-many>, or <many-to-any>. + The first two map elements with value semantics, the other three are used to map + entity associations. - All collection types except Set and bag have an index - column - a column that maps to an array or List index or - Map key. The index of a Map may be of any - basic type, an entity type or even a composite type (it may not be a collection). The - index of an array or list is always of type integer. Indexes are - mapped using <index>, <index-many-to-many>, - <composite-index> or <index-many-to-any>. + All collection mappings, except those with set and bag semantics, need an + index column in the collection table - a column that maps to an + array index, or List index, or Map key. The + index of a Map may be of any basic type, it may be an entity reference, + or even a composite type (it may not be a collection). The index of an array or list is + always of type integer. Indexes are mapped using + <index>, <index-many-to-many>, + <composite-index>, or <index-many-to-any>. @@ -270,7 +280,7 @@ kittens = cat.getKittens(); //Okay, kittens collection is a Set - + Collections of Values and Many-To-Many Associations @@ -390,9 +400,8 @@ kittens = cat.getKittens(); //Okay, kittens collection is a Set - A collection of entities with its own table corresponds to the relational notion - of many-to-many association. A many to many association is the - most natural mapping of a Java collection but is not usually the best relational model. + A collection of entity references, where the references are held in a separate table + corresponds to the relational notion of many-to-many association. @@ -404,7 +413,7 @@ kittens = cat.getKittens(); //Okay, kittens collection is a Set ]]> @@ -419,9 +428,13 @@ kittens = cat.getKittens(); //Okay, kittens collection is a Set - outer-join (optional - defaults to auto): - enables outer-join fetching for this association when - hibernate.use_outer_join is set. + fetch (optional - defaults to join): + enables outer-join or sequential select fetching for this association. This + is a special case, for full eager fetching (in a single SELECT) + of an entity and its many-to-many relationships to other entities, you would + enable join fetching not only of the collection itself, + but also with this attribute on the <many-to-many> + nested element. @@ -566,7 +579,7 @@ kittens = cat.getKittens(); //Okay, kittens collection is a Set - + Sorted Collections @@ -605,7 +618,7 @@ kittens = cat.getKittens(); //Okay, kittens collection is a Set memory. - + @@ -678,7 +691,7 @@ kittens = cat.getKittens(); //Okay, kittens collection is a Set - + Bidirectional Associations @@ -716,9 +729,13 @@ kittens = cat.getKittens(); //Okay, kittens collection is a Set You may specify a bidirectional many-to-many association simply by mapping two many-to-many associations to the same database table and declaring one end as - inverse (which one is your choice). Here's an example of - a bidirectional many-to-many association from a class back to itself - (each category can have many items and each item can be in many categories): + inverse (which one is your choice, but it can not be an + indexed collection). + + + + Here's an example of a bidirectional many-to-many association; each category can + have many items and each item can be in many categories: @@ -753,18 +770,18 @@ kittens = cat.getKittens(); //Okay, kittens collection is a Set category.getItems().add(item); // The category now "knows" about the relationship item.getCategories().add(category); // The item now "knows" about the relationship -session.update(item); // No effect, nothing will be saved! -session.update(category); // The relationship will be saved]]> +session.create(item); // The relationship won't be saved! +session.create(category); // The relationship will be saved]]> The non-inverse side is used to save the in-memory representation to the database. We would get an unneccessary INSERT/UPDATE and probably even a foreign key violation - if both would trigger changes! The same is of course also true for bidirectional - one-to-many associations. + if both would trigger changes! - You may map a bidirectional one-to-many association by mapping a one-to-many association + The same is of course also true for bidirectional one-to-many associations. You may + map a bidirectional one-to-many association by mapping a one-to-many association to the same table column(s) as a many-to-one association and declaring the many-valued end inverse="true". diff --git a/reference/en/modules/component_mapping.xml b/reference/en/modules/component_mapping.xml index 2c92b050ff..090506f1eb 100644 --- a/reference/en/modules/component_mapping.xml +++ b/reference/en/modules/component_mapping.xml @@ -10,8 +10,8 @@ Dependent objects - A component is a contained object that is persisted as a value type, not an entity. - The term "component" refers to the object-oriented notion of composition + A component is a contained object that is persisted as a value type, not an entity + reference. The term "component" refers to the object-oriented notion of composition (not to architecture-level components). For example, you might model a person like this: @@ -97,10 +97,12 @@ - Like all value types, components do not support shared references. The null - value semantics of a component are ad hoc. When reloading the - containing object, Hibernate will assume that if all component columns are - null, then the entire component is null. This should be okay for most purposes. + Like all value types, components do not support shared references. In other words, two + persons could have the same name, but the two person objects would contain two independent + name ojects, only "the same" by value. The null value semantics of a component are + ad hoc. When reloading the containing object, Hibernate will assume + that if all component columns are null, then the entire component is null. This should + be okay for most purposes. @@ -131,7 +133,7 @@ - + Collections of dependent objects @@ -202,6 +204,14 @@ ]]> + + Of course, there can't be a reference to the purchae on the other side, for + bidirectional association navigation. Remember that components are value types and + don't allow shared references. A single Purchase can be in the + set of an Order, but it can't be referenced by the Item + at the same time. + + Even ternary (or quaternary, etc) associations are possible: @@ -268,6 +278,10 @@ previous session. + + TODO: document new auto-detect features for assigned IDs in H3 + + So, if you wish to use transitive reattachment (you don't have to), you must either implement Interceptor.isUnsaved() or define the diff --git a/reference/en/modules/inheritance_mapping.xml b/reference/en/modules/inheritance_mapping.xml index 3912c09140..89a2eabaf5 100644 --- a/reference/en/modules/inheritance_mapping.xml +++ b/reference/en/modules/inheritance_mapping.xml @@ -4,6 +4,11 @@ The Three Strategies + + TODO: While this is all still supported, many new features would require + a rewrite of this whole chapter + + Hibernate supports the three basic inheritance mapping strategies.