Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lect17-hibernate-orm / more / hibernate_reference.pdf
Скачиваний:
93
Добавлен:
18.03.2015
Размер:
2 Мб
Скачать
☆

Chapter 7. Collection mapping

</bag> </class>

<class name="Item">

<id name="id" column="ITEM_ID"/>

...

<!-- inverse end -->

<bag name="categories" table="CATEGORY_ITEM" inverse="true">

<key column="ITEM_ID"/>

<many-to-many class="Category" column="CATEGORY_ID"/>

</bag> </class>

Changes made only to the inverse end of the association are not persisted. This means that Hibernate has two representations in memory for every bidirectional association: one link from A to B and another link from B to A. This is easier to understand if you think about the Java object model and how a many-to-many relationship in Javais created:

Example 7.28. Effect of inverse vs. non-inverse side of many to many

associations

category.getItems().add(item);

// The

category

now "knows"

about

the relationship

item.getCategories().add(category);

// The

item now

"knows" about the

relationship

session.persist(item);

//

The

relationship

won't be saved!

session.persist(category);

//

The

relationship

will be

saved

 

 

 

 

 

 

 

 

 

The non-inverse side is used to save the in-memory representation to the database.

7.3.3. Bidirectional associations with indexed collections

There are some additional considerations for bidirectional mappings with indexed collections (where one end is represented as a <list> or <map>) when using Hibernate mapping files. If there is a property of the child class that maps to the index column you can use inverse="true" on the collection mapping:

Example 7.29. Bidirectional association with indexed collection

<class name="Parent">

<id name="id" column="parent_id"/>

....

<map name="children" inverse="true">

<key column="parent_id"/> <map-key column="name"

type="string"/>

<one-to-many class="Child"/> </map>

</class>

176

Ternary associations

<class name="Child">

<id name="id" column="child_id"/>

....

<property name="name" not-null="true"/>

<many-to-one name="parent"

class="Parent"

column="parent_id" not-null="true"/>

</class>

If there is no such property on the child class, the association cannot be considered truly bidirectional. That is, there is information available at one end of the association that is not available at the other end. In this case, you cannot map the collection inverse="true". Instead, you could use the following mapping:

Example 7.30. Bidirectional association with indexed collection, but no

index column

<class name="Parent">

<id name="id" column="parent_id"/>

....

<map name="children">

<key column="parent_id" not-null="true"/> <map-key column="name" type="string"/>

<one-to-many class="Child"/> </map>

</class>

<class name="Child">

<id name="id" column="child_id"/>

....

<many-to-one name="parent"

class="Parent"

column="parent_id"

insert="false"

update="false"

not-null="true"/>

</class>

Note that in this mapping, the collection-valued end of the association is responsible for updates

to the foreign key.

7.3.4. Ternary associations

There are three possible approaches to mapping a ternary association. One approach is to use a Map with an association as its index:

177

Chapter 7. Collection mapping

Example 7.31. Ternary association mapping

@Entity

public class Company { @Id

int id;

...

@OneToMany // unidirectional @MapKeyJoinColumn(name="employee_id") Map<Employee, Contract> contracts;

}

// or

<map name="contracts">

<key column="employer_id" not-null="true"/> <map-key-many-to-many column="employee_id" class="Employee"/> <one-to-many class="Contract"/>

</map>

A second approach is to remodel the association as an entity class. This is the most common approach. A final alternative is to use composite elements, which will be discussed later.

7.3.5. Using an <idbag>

The majority of the many-to-many associations and collections of values shown previously all map to tables with composite keys, even though it has been suggested that entities should have synthetic identifiers (surrogate keys). A pure association table does not seem to benefit much from a surrogate key, although a collection of composite values might. For this reason Hibernate provides a feature that allows you to map many-to-many associations and collections of values to a table with a surrogate key.

The <idbag> element lets you map a List (or Collection) with bag semantics. For example:

<idbag name="lovers" table="LOVERS"> <collection-id column="ID" type="long">

<generator class="sequence"/>

</collection-id>

<key column="PERSON1"/>

<many-to-many column="PERSON2" class="Person" fetch="join"/> </idbag>

An <idbag> has a synthetic id generator, just like an entity class. A different surrogate key is assigned to each collection row. Hibernate does not, however, provide any mechanism for discovering the surrogate key value of a particular row.

The update performance of an <idbag> supersedes a regular <bag>. Hibernate can locate individual rows efficiently and update or delete them individually, similar to a list, map or set.

178

Соседние файлы в папке more