Hibernate Annotations
From CSWiki
Introduction to Hibernate 3 Annotations
Hibernate relies on external XML files for its configuration: database mappings are defined in a set of XML mapping files and loaded at startup time. There are many ways to create these mappings, either automatically, from an existing database schema or Java class model, or by hand. In any case, you can end up with a considerable number of Hibernate mapping files. Alternatively, you can use tools like XDoclet to generate the mapping files from javadoc-style annotations, though this adds an extra step in your build process. In recent versions of Hibernate, a new, more elegant approach has emerged, based on Java 5 annotations. Using the new Hibernate Annotations library, you can dispense once and for all with your old mapping files--everything is defined as, you guessed it--annotations directly embedded in your Java classes. It turns out that annotations provide a powerful and flexible way of declaring persistence mappings. They are also well supported in recent Java IDEs, with automatic code completion and syntax highlighting.
Installing Hibernate Annotations
To use Hibernate Annotations, you will need at least Hibernate 3.2, and of course Java 5. You can download both Hibernate 3.2 and the Hibernate Annotations library from the Hibernate web site. In addition to the standard Hibernate JARs and dependencies, you will also need the Hibernate Annotations .jar file (hibernate-annotations.jar) Java Persistence API (lib/ejb3-persistence.jar).
Hibernate configuration file
The next step is to obtain a Hibernate session factory. You do this a little differently using Hibernate Annotations, You have to use the AnnotationConfiguration class to set up your session factory
sessionFactory = new AnnotationConfiguration().buildSessionFactory();
As usual, you need to declare your persistence classes in the Hibernate configuration file (typically hibernate.cfg.xml), though you use the <mapping> element to declare your persistent classes:
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<mapping class="com.csula.cs590.model.User"/>
<mapping class="com.csula.cs590.model.Course"/>
</session-factory>
</hibernate-configuration>
Hibernate configuration file with Spring
Using the Spring framework, you can set up an annotation-based Hibernate session factory using the AnnotationSessionFactoryBean class, as shown here:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource">
Cite error 3; Invalid <ref> tag; invalid names, e.g. too many
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MysqlDialect</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
...
</props>
</property>
<property name="annotatedClasses">
<list>
<value>com.csula.cs590.model.User</value>
<value>com.csula.cs590.model.Course</value>
...
</list>
</property>
</bean>
Persistent Class
Annotated persistent classes are ordinary POJOs, just like in any other Hibernate application. Here's a simple example:
@Entity
public class User {
private Long id;
private String name;
@Id
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
The @Entity annotation declares the class to be persistent. The @Id annotation lets you indicate which property is the unique identifier for this class.
Primary Keys
One thing Hibernate is good at is automatically generating primary keys. The following example illustrates a frequently used approach, where Hibernate will decide on an appropriate key generation strategy depending on the underlying database:
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Long getId() {
return id;
}
Customizing Table and Field Mappings
By default, Hibernate will map persistent classes to tables and fields with matching names. For example, the above class would map to a table along the following lines:
CREATE TABLE USER ( ID long, NAME varchar )
You can use the @Table and @Column annotations to tailor your persistence mappings, as shown here:
@Entity
@Table(name="USER")
public class User {
private Long id;
private String name;
@Id
@Column(name="USER_ID")
public Long getId()
{
return id;
}
public void setId(Long id)
{
this.id = id;
}
@Column(name="USER_NAME")
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
}
This would map to the following table:
CREATE TABLE USER( USER_ID long, USER_NAME varchar )
You can also customize your mappings using other table and column attributes. This lets you specify details such as column length, non-null constraints and so forth. Hibernate supports a large number of attributes for these annotations. Here are just a few:
...
@Column(name="USER_ID", length=80, nullable=true)
public String getName() {
return name;
}
...
Mapping Relationships
One of the most commonly-used relationships are many-to-one relationships. Suppose, in the above example, that each Uer is associated with a Course via a many-to-one relationship. You could map this as follows:
@ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
public Course getCourse() {
return course;
}
The CascadeType values indicate how Hibernate should handle cascading operations.
Another commonly-used relationship is the opposite of the above: the one-to-many-to-one relationship, also known as a collection. You could map this as follows:
@OneToMany(mappedBy="course", cascade=CascadeType.ALL, fetch=FetchType.EAGER)
@OrderBy("name")
public List<User> getUsers() {
return users;
}
Named Queries
One of the nice features of Hibernate is the ability to declare named queries within your mapping files. These queries can then be invoked by name from within the code, which lets you centralize queries and avoids having SQL or HQL code scattered throughout the application. You can do this with annotations too, using the @NamedQueries and @NamedQuery annotations, as shown here:
@NamedQueries(
{
@NamedQuery(
name="course.findById",
query="select c from Course c left join fetch c.users where id=:id"
),
@NamedQuery(
name="course.findAll",
query="select c from Course c"
),
@NamedQuery(
name="delete.delete",
query="delete from Course where id=:id"
)
}
)
Once defined, you can call them just as you would any other named query.
Links
- Hibernate - Hibernate Annotations

