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

Chapter 5. Basic O/R Mapping

source="vm|db"

generated="never|always"

node="element-name|@attribute-name|element/@attribute|."

/>

column (optional - defaults to the property name): the name of a column holding the timestamp.

name: the name of a JavaBeans style property of Java type Date or Timestamp of the persistent class.

access (optional - defaults to property): the strategy Hibernate uses for accessing the property value.

unsaved-value (optional - defaults to null): a version property value that indicates that an instance is newly instantiated (unsaved), distinguishing it from detached instances that were saved or loaded in a previous session. Undefined specifies that the identifier property value should be used.

source (optional - defaults to vm): Where should Hibernate retrieve the timestamp value from? From the database, or from the current JVM? Database-based timestamps incur an overhead because Hibernate must hit the database in order to determine the "next value". It is safer to use in clustered environments. Not all Dialects are known to support the retrieval of the database's current timestamp. Others may also be unsafe for usage in locking due to lack of precision (Oracle 8, for example).

generated (optional - defaults to never): specifies that this timestamp property value is actually generated by the database. See the discussion of generated properties for more information.

Note

<Timestamp> is equivalent to <version type="timestamp">. And <timestamp source="db"> is equivalent to <version type="dbtimestamp">

5.1.4. Property

You need to decide which property needs to be made persistent in a given entity. This differs slightly between the annotation driven metadata and the hbm.xml files.

5.1.4.1. Property mapping with annotations

In the annotations world, every non static non transient property (field or method depending on the access type) of an entity is considered persistent, unless you annotate it as @Transient. Not having an annotation for your property is equivalent to the appropriate @Basic annotation.

The @Basic annotation allows you to declare the fetching strategy for a property. If set to LAZY, specifies that this property should be fetched lazily when the instance variable is first accessed. It requires build-time bytecode instrumentation, if your classes are not instrumented, property level

94

Property

lazy loading is silently ignored. The default is EAGER. You can also mark a property as not optional thanks to the @Basic.optional attribute. This will ensure that the underlying column are not nullable (if possible). Note that a better approach is to use the @NotNull annotation of the Bean Validation specification.

Let's look at a few examples:

public transient int counter; //transient property

private String firstname; //persistent property

@Transient

String getLengthInMeter() { ... } //transient property

String getName() {... } // persistent property

@Basic

int getLength() { ... } // persistent property

@Basic(fetch = FetchType.LAZY)

String getDetailedComment() { ... } // persistent property

@Temporal(TemporalType.TIME)

java.util.Date getDepartureTime() { ... } // persistent property

@Enumerated(EnumType.STRING)

Starred getNote() { ... } //enum persisted as String in database

counter, a transient field, and lengthInMeter, a method annotated as @Transient, and will be ignored by the Hibernate. name, length, and firstname properties are mapped persistent and eagerly fetched (the default for simple properties). The detailedComment property value will be lazily fetched from the database once a lazy property of the entity is accessed for the first time.

Usually you don't need to lazy simple properties (not to be confused with lazy association fetching). The recommended alternative is to use the projection capability of JP-QL (Java Persistence Query Language) or Criteria queries.

JPA support property mapping of all basic types supported by Hibernate (all basic Java types , their respective wrappers and serializable classes). Hibernate Annotations supports out of the box enum type mapping either into a ordinal column (saving the enum ordinal) or a string based column (saving the enum string representation): the persistence representation, defaulted to ordinal, can be overridden through the @Enumerated annotation as shown in the note property example.

In plain Java APIs, the temporal precision of time is not defined. When dealing with temporal data you might want to describe the expected precision in database. Temporal data can have

DATE, TIME, or TIMESTAMP precision (ie the actual date, only the time, or both). Use the @Temporal annotation to fine tune that.

@Lob indicates that the property should be persisted in a Blob or a Clob depending on the property type: java.sql.Clob, Character[], char[] and java.lang.String will be persisted in a Clob. java.sql.Blob, Byte[], byte[] and Serializable type will be persisted in a Blob.

95

Chapter 5. Basic O/R Mapping

@Lob

public String getFullText() { return fullText;

}

@Lob

public byte[] getFullCode() { return fullCode;

}

If the property type implements java.io.Serializable and is not a basic type, and if the property is not annotated with @Lob, then the Hibernate serializable type is used.

5.1.4.1.1. Type

You can also manually specify a type using the @org.hibernate.annotations.Type and some parameters if needed. @Type.type could be:

1.The name of a Hibernate basic type: integer, string, character, date, timestamp, float, binary, serializable, object, blob etc.

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.

@org.hibernate.annotations.TypeDef and @org.hibernate.annotations.TypeDefs allows you to declare type definitions. These annotations can be placed at the class or package level. Note that these definitions are global for the session factory (even when defined at the class level). If the type is used on a single entity, you can place the definition on the entity itself. Otherwise, it is recommended to place the definition at the package level. In the example below, when Hibernate encounters a property of class PhoneNumer, it delegates the persistence strategy to the custom mapping type PhoneNumberType. However, properties belonging to other classes, too, can delegate their persistence strategy to PhoneNumberType, by explicitly using the @Type annotation.

Note

Package level annotations are placed in a file named package-info.java in the appropriate package. Place your annotations before the package declaration.

@TypeDef(

name = "phoneNumber",

defaultForType = PhoneNumber.class,

96

Property

typeClass = PhoneNumberType.class

)

@Entity

public class ContactDetails {

[...]

private PhoneNumber localPhoneNumber; @Type(type="phoneNumber")

private OverseasPhoneNumber overseasPhoneNumber;

[...]

}

The following example shows the usage of the parameters attribute to customize the TypeDef.

//in org/hibernate/test/annotations/entity/package-info.java

@TypeDefs(

{

@TypeDef(

name="caster",

typeClass = CasterStringType.class,

parameters = {

@Parameter(name="cast", value="lower")

}

)

}

)

package org.hibernate.test.annotations.entity;

//in org/hibernate/test/annotations/entity/Forest.java

public class Forest {

@Type(type="caster")

public String getSmallText() {

...

}

When using composite user type, you will have to express column definitions. The @Columns has been introduced for that purpose.

@Type(type="org.hibernate.test.annotations.entity.MonetaryAmountUserType") @Columns(columns = {

@Column(name="r_amount"), @Column(name="r_currency")

})

public MonetaryAmount getAmount() { return amount;

}

public class MonetaryAmount implements Serializable { private BigDecimal amount;

private Currency currency;

...

97

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