Sunday, September 20, 2009

Hibernate: Mapping definition xml

  • The mapping definition starts with the hibernate-mapping element.
  • The package attribute sets the default package for unqualified class names in the mapping.With this attribute set, you need only give the class name for other persistent classes listed in the mapping file
  • To refer to a persistent class outside the given package, you must provide the fully qualified class name within the mapping document.
  • If Hibernate has trouble locating a class because of a missing package on, for instance, a many-to-one element, Hibernate throws a MappingException.
  • Immediately after the hibernate-mapping tag, you encounter the class tag. The class tag begins the mapping definition for a specific persistent class.
  • The table attribute names the relational table used to store the state of the object.
  • The id element describes the primary key for the persistent class as well as how the key value is generated.
  • Each persistent class must have an id element declaring the primary key for the relational table.
  • The name attribute defines the property in your persistent class that will be used to store the primary key value.
  • If the column for the primary key has a different name than your object property, the column attribute is used.
  • The values of the type and unsaved-value attributes depend on the generator used.
  • The generator creates the primary key value for the persistent class. Hibernate provides multiple generator implementations that use various methods to create primary key values. Ex : assigned, native
  • The native generator returns a short, integer, or long value. You’ve set the type attribute to long, and the id property in the Event object has a type of java.lang.Long. The value of the type attribute and the property type in the object must be the same.
  • The unsaved-value attribute describes the value of the id property for transient instances of this class. The unsaved-value attribute affects how objects are stored.
  • Each property element corresponds to a property in the java object. The name attribute contains the property name, whereas the type attribute specifies the property object type.
  • The column used to store the property value defaults to the property name. The column attribute overrides this default behavior.
  • If the type attribute is omitted, Hibernate determines the type using runtime reflection. In certain cases, you must provide the property type, since reflection may not be able to determine the desired type (such as differentiating between the Hibernate DATE and TIMESTAMP types).
  • The property element may also contain the name of a serializable Java class or a user-defined type. You create a new user-defined type by implementing either the org.hibernate.UserType or org.hibernate. CompositeUserType interface.

Many-to-one element

Many-to-one associations use foreign keys to maintain the association between two persistent classes. Although the figure doesn’t display it, this association is unidirectional, meaning you can navigate from the Event instance to the Location but not from the Location to the Event instance.

Figure 3.2 page 60


<many-to-one name="location" column="location_id" class="Location">

The
name attribute gives the name of the property in the object, and the optional column attribute specifies the column used to store the foreign key to the locations table. If you don’t give a column attribute, the name attribute is used as the column name. The class attribute names the associated persistent class.


many-to-one relationship
lazy

lazy meaning that the associated object won’t be retrieved when the parent object is retrieved. The solution is to use proxied objects.

Object proxies can be defined in one of two ways. First, you can add a proxy attribute to the class element. You can either specify a different class or use the persistent class as the proxy. For example:


<class name="Location"
proxy="com.manning.hq.ch03.Location"...>...
</class>

The second method is to use the lazy attribute. Setting lazy="true" is a shorthand way of defining the persistent class as the proxy. Let’s assume the Location class is defined as lazy:

<class name="Location" lazy="true"...>...</class>

The lazy attribute is true by default in Hibernate 3.

An easy way to disable all proxies, including lazy collections, is to set the
default-lazy attribute to true in the hibernate-mapping element


Session session = factory.openSession();
Event ev = (Event) session.load(Event.class, myEventId);
Location loc = ev.getLocation();
String name = loc.getName();
session.close();

The returned Location instance is a proxy. Hibernate populates the Location instance when
getName() is called.

If you’ve guessed that you can call
loc.getId() without invoking a call to the database, you’re correct. The proxied object already contains the ID value

Collections

The collections are defined as sets, meaning Hibernate manages the collections with the same semantics as a java.util.Set:

<set name="speakers">
<key column="event_id"/>
<one-to-many class="Speaker"/>
</set>

This definition declares that the Event class has a property named speakers, and that it’s a Set containing instances of the Speaker class.


The key element defines the foreign key from the collection table to the parent table. In this case, the speakers table has an event_id column referring to the id column in the events table. The one-to-many element defines the association to the Speaker class.


We’ve only touched on persisting collections with Hibernate. In addition to Sets, Hibernate also supports persistent Maps and Lists, as well as arrays of objects and primitive values.


Location of the mapping file

Suppose the class file for the Event object is stored in the com/manning/hq directory and therefore in the com.manning.hq package. The Event.hbm.xml file should also be stored in the com/manning/hq directory inside the JAR archive.


Cascades

Hibernate supports ten different types of cascades that can be applied to many-to-one associations as well as collections. The default cascade is none. Each cascade strategy specifies the operation or operations that should be propagated to child entities. The cascade types that you are most likely to use are the following:


  • all—All operations are passed to child entities: save, update, and delete.
  • save-update—Save and update (INSERT and UPDATE, respectively) are passed to child entities.
  • delete—Deletion operations are passed to child entities.
  • delete-orphan—All operations are passed to child entities, and objects no longer associated with the parent object are deleted.

The cascade element is added to the desired many-to-one or collection element. For example, the following configuration instructs Hibernate to delete the child Speaker elements when the parent Event is deleted:


<set name="speakers" cascade="delete">
<key column="event_id"/>
<one-to-many class="Speaker"/>
</set>


It’s important to note that Hibernate doesn’t pass the cascade off to the database. Instead, the Hibernate service manages the cascades internally. This is necessary because Hibernate has to know exactly which objects are saved, updated, and deleted.


When an object has one or more associated objects, there are two options. You can either retrieve associated objects using an outer join or by using a separate SELECT statement.


<many-to-one name="location" class="Location" fetch="join"/>

When an Event instance is loaded, the associated Location instance will
be loaded using an outer join. If you wanted to use a separate select,
the many-to-one element would look like this:

<many-to-one name="location" class="Location" fetch="select"/>


This also applies to child collections, but you can only fetch one collection using a join per persistent object. Additional collections must be fetched using the SELECT strategy.










No comments:

Post a Comment