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

Embedded objects (aka components)

2.The name of a Java class with a default basic type: int, float, char, java.lang.String, java.util.Date, java.lang.Integer, java.sql.Clob etc.

3.The name of a serializable Java class.

4.The class name of a custom type: com.illflow.type.MyCustomType etc.

If you do not specify a type, Hibernate will use reflection upon the named property and guess the correct Hibernate type. Hibernate will attempt to interpret the name of the return class of the property getter using, in order, rules 2, 3, and 4. In certain cases you will need the type attribute. For example, to distinguish between Hibernate.DATE and Hibernate.TIMESTAMP, or to specify a custom type.

The access attribute allows you to control how Hibernate accesses the property at runtime. By default, Hibernate will call the property get/set pair. If you specify access="field", Hibernate will bypass the get/set pair and access the field directly using reflection. You can specify your own strategy for property access by naming a class that implements the interface org.hibernate.property.PropertyAccessor.

A powerful feature is derived properties. These properties are by definition read-only. The property value is computed at load time. You declare the computation as an SQL expression. This then translates to a SELECT clause subquery in the SQL query that loads an instance:

<property name="totalPrice"

formula="( SELECT SUM (li.quantity*p.price) FROM LineItem li, Product p

WHERE li.productId = p.productId

AND li.customerId = customerId

AND li.orderNumber = orderNumber )"/>

You can reference the entity table by not declaring an alias on a particular column. This would be customerId in the given example. You can also use the nested <formula> mapping element if you do not want to use the attribute.

5.1.5. Embedded objects (aka components)

Embeddable objects (or components) are objects whose properties are mapped to the same table as the owning entity's table. Components can, in turn, declare their own properties, components or collections

It is possible to declare an embedded component inside an entity and even override its column mapping. Component classes have to be annotated at the class level with the @Embeddable annotation. It is possible to override the column mapping of an embedded object for a particular entity using the @Embedded and @AttributeOverride annotation in the associated property:

@Entity

public class Person implements Serializable {

// Persistent component using defaults

103

Chapter 5. Basic O/R Mapping

Address homeAddress;

@Embedded @AttributeOverrides( {

@AttributeOverride(name="iso2", column = @Column(name="bornIso2") ), @AttributeOverride(name="name", column = @Column(name="bornCountryName") )

} )

Country bornIn;

...

}

@Embeddable

public class Address implements Serializable { String city;

Country nationality; //no overriding here

}

@Embeddable

public class Country implements Serializable { private String iso2;

@Column(name="countryName") private String name;

public String getIso2() { return iso2; }

public void setIso2(String iso2) { this.iso2 = iso2; }

public String getName() { return name; }

public void setName(String name) { this.name = name; }

...

}

An embeddable object inherits the access type of its owning entity (note that you can override that using the @Access annotation).

The Person entity has two component properties, homeAddress and bornIn. homeAddress property has not been annotated, but Hibernate will guess that it is a persistent component by looking for the @Embeddable annotation in the Address class. We also override the mapping of a column name (to bornCountryName) with the @Embedded and @AttributeOverride annotations for each mapped attribute of Country. As you can see, Country is also a nested component of Address, again using auto-detection by Hibernate and JPA defaults. Overriding columns of embedded objects of embedded objects is through dotted expressions.

@Embedded @AttributeOverrides( {

@AttributeOverride(name="city", column = @Column(name="fld_city") ), @AttributeOverride(name="nationality.iso2", column = @Column(name="nat_Iso2") ),

@AttributeOverride(name="nationality.name", column = @Column(name="nat_CountryName") ) //nationality columns in homeAddress are overridden

} )

104

Embedded objects (aka components)

Address homeAddress;

Hibernate Annotations supports something that is not explicitly supported by the JPA specification. You can annotate a embedded object with the @MappedSuperclass annotation to make the superclass properties persistent (see @MappedSuperclass for more informations).

You can also use association annotations in an embeddable object (ie @OneToOne,

@ManyToOne, @OneToMany or @ManyToMany). To override the association columns you can use

@AssociationOverride.

If you want to have the same embeddable object type twice in the same entity, the column name defaulting will not work as several embedded objects would share the same set of columns. In plain JPA, you need to override at least one set of columns. Hibernate, however, allows you to enhance the default naming mechanism through the NamingStrategy interface. You can write a strategy that prevent name clashing in such a situation. DefaultComponentSafeNamingStrategy is an example of this.

If a property of the embedded object points back to the owning entity, annotate it with the @Parent annotation. Hibernate will make sure this property is properly loaded with the entity reference.

In XML, use the <component> element.

<component

name="propertyName"

class="className"

insert="true|false"

update="true|false"

access="field|property|ClassName"

lazy="true|false"

optimistic-lock="true|false"

unique="true|false" node="element-name|."

>

<property ...../> <many-to-one .... />

........

</component>

name: the name of the property.

class (optional - defaults to the property type determined by reflection): the name of the component (child) class.

insert: do the mapped columns appear in SQL INSERTs? update: do the mapped columns appear in SQL UPDATEs?

105

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