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

Chapter 5. Basic O/R Mapping

The UserType can now retrieve the value for the parameter named default from the Properties object passed to it.

If you regularly use a certain UserType, it is useful to define a shorter name for it. You can do this using the <typedef> element. Typedefs assign a name to a custom type, and can also contain a list of default parameter values if the type is parameterized.

<typedef class="com.mycompany.usertypes.DefaultValueIntegerType" name="default_zero"> <param name="default">0</param>

</typedef>

<property name="priority" type="default_zero"/>

It is also possible to override the parameters supplied in a typedef on a case-by-case basis by using type parameters on the property mapping.

Even though Hibernate's rich range of built-in types and support for components means you will rarely need to use a custom type, it is considered good practice to use custom types for nonentity classes that occur frequently in your application. For example, a MonetaryAmount class is a good candidate for a CompositeUserType, even though it could be mapped as a component. One reason for this is abstraction. With a custom type, your mapping documents would be protected against changes to the way monetary values are represented.

5.3. Mapping a class more than once

It is possible to provide more than one mapping for a particular persistent class. In this case, you must specify an entity name to disambiguate between instances of the two mapped entities. By default, the entity name is the same as the class name. Hibernate lets you specify the entity name when working with persistent objects, when writing queries, or when mapping associations to the named entity.

<class name="Contract" table="Contracts" entity-name="CurrentContract">

...

<set name="history" inverse="true" order-by="effectiveEndDate desc">

<key column="currentContractId"/>

<one-to-many entity-name="HistoricalContract"/> </set>

</class>

<class name="Contract" table="ContractHistory" entity-name="HistoricalContract">

...

<many-to-one name="currentContract"

column="currentContractId"

entity-name="CurrentContract"/>

138

SQL quoted identifiers

</class>

Associations are now specified using entity-name instead of class.

Note

This feature is not supported in Annotations

5.4. SQL quoted identifiers

You can force Hibernate to quote an identifier in the generated SQL by enclosing the table or column name in backticks in the mapping document. Hibernate will use the correct quotation style for the SQL Dialect. This is usually double quotes, but the SQL Server uses brackets and MySQL uses backticks.

@Entity @Table(name="`Line Item`") class LineItem {

@id @Column(name="`Item Id`") Integer id; @Column(name="`Item #`") int itemNumber

}

<class name="LineItem" table="`Line Item`">

<id name="id" column="`Item Id`"/><generator class="assigned"/></id> <property name="itemNumber" column="`Item #`"/>

...

</class>

5.5. Generated properties

Generated properties are properties that have their values generated by the database. Typically, Hibernate applications needed to refresh objects that contain any properties for which the database was generating values. Marking properties as generated, however, lets the application delegate this responsibility to Hibernate. When Hibernate issues an SQL INSERT or UPDATE for an entity that has defined generated properties, it immediately issues a select afterwards to retrieve the generated values.

Properties marked as generated must additionally be non-insertable and non-updateable. Only versions, timestamps, and simple properties, can be marked as generated.

never (the default): the given property value is not generated within the database.

insert: the given property value is generated on insert, but is not regenerated on subsequent updates. Properties like created-date fall into this category. Even though version and timestamp properties can be marked as generated, this option is not available.

always: the property value is generated both on insert and on update.

139

Chapter 5. Basic O/R Mapping

To mark a property as generated, use @Generated.

5.6. Column transformers: read and write expressions

Hibernate allows you to customize the SQL it uses to read and write the values of columns mapped to simple properties. For example, if your database provides a set of data encryption functions, you can invoke them for individual columns like this:

@Entity

class CreditCard {

@Column(name="credit_card_num")

@ColumnTransformer(

read="decrypt(credit_card_num)", write="encrypt(?)")

public String getCreditCardNumber() { return creditCardNumber; }

public void setCreditCardNumber(String number) { this.creditCardNumber = number; } private String creditCardNumber;

}

or in XML

<property name="creditCardNumber">

<column

name="credit_card_num" read="decrypt(credit_card_num)" write="encrypt(?)"/>

</property>

Note

You can use the plural form @ColumnTransformers if more than one columns need to define either of these rules.

If a property uses more that one column, you must use the forColumn attribute to specify which column, the expressions are targeting.

@Entity

class User {

@Type(type="com.acme.type.CreditCardType")

@Columns( {

@Column(name="credit_card_num"), @Column(name="exp_date") } )

@ColumnTransformer(

forColumn="credit_card_num", read="decrypt(credit_card_num)", write="encrypt(?)")

public CreditCard getCreditCard() { return creditCard; }

140

Auxiliary database objects

public void setCreditCard(CreditCard card) { this.creditCard = card; }

private CreditCard creditCard;

}

Hibernate applies the custom expressions automatically whenever the property is referenced in a query. This functionality is similar to a derived-property formula with two differences:

•The property is backed by one or more columns that are exported as part of automatic schema generation.

•The property is read-write, not read-only.

The write expression, if specified, must contain exactly one '?' placeholder for the value.

5.7. Auxiliary database objects

Auxiliary database objects allow for the CREATE and DROP of arbitrary database objects. In conjunction with Hibernate's schema evolution tools, they have the ability to fully define a user schema within the Hibernate mapping files. Although designed specifically for creating and dropping things like triggers or stored procedures, any SQL command that can be run via a java.sql.Statement.execute() method is valid (for example, ALTERs, INSERTS, etc.). There are essentially two modes for defining auxiliary database objects:

The first mode is to explicitly list the CREATE and DROP commands in the mapping file:

<hibernate-mapping>

...

<database-object>

<create>CREATE TRIGGER my_trigger ...</create> <drop>DROP TRIGGER my_trigger</drop>

</database-object> </hibernate-mapping>

The second mode is to supply a custom class that constructs the CREATE and DROP commands. This custom class must implement the org.hibernate.mapping.AuxiliaryDatabaseObject interface.

<hibernate-mapping>

...

<database-object>

<definition class="MyTriggerDefinition"/> </database-object>

</hibernate-mapping>

Additionally, these database objects can be optionally scoped so that they only apply when certain

dialects are used.

141

Chapter 5. Basic O/R Mapping

<hibernate-mapping>

...

<database-object>

<definition class="MyTriggerDefinition"/>

<dialect-scope name="org.hibernate.dialect.Oracle9iDialect"/> <dialect-scope name="org.hibernate.dialect.Oracle10gDialect"/>

</database-object> </hibernate-mapping>

Note

This feature is not supported in Annotations

142

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