In the last, introductory article I mentioned the so-called “XML-Hell” which is the massive usage of XML to do Hibernate configuration. In this article, I will introduce the annotation-based configuration, where you can use Hibernate’s annotations on the entities to reduce the amount of XML needed.
Why annotations are good
As you will see in the example code: with annotations, you see in the entity class definition itself what the property-mappings are so you do not need to look-up the right .hbm.xml file to find the mapping definition.
And as a nice side-effect: you need to modify only the entity. For example, if you want to add a new Date field to the Book class, you need to add the mapping in the Book.hbm.xml file too. With annotations, it is only a change in the Java class. You’ll find an example on using dates later in this article.
An example
In this example, I will continue to use the Book entity introduced in the first article. Now I will convert the POJO to use annotations instead of XML configuration — and I will stay with this later on in this series. This is because annotations are easier to read and find than XML.
The entity
For the entity, I need to add some annotations to represent the same mappings as in the XML file.
The first one is to tell Hibernate that the Book class is an entity. We can achieve this with the javax.persistence.@Entity annotation. Without this, Hibernate would throw an exception at startup with the error message that “hibernate_example.Book” is an unknown entity.
Next one is the table definition. I add books to the BOOKS table. Without an explicit table definition, Hibernate would add the entity to the BOOK table. In general, I can say that without a table definition entities are saved in a table named the same as the entity class. To name a table I have to use javax.persistence.@Table on the class. This annotation has a parameter called name. This name defines the name of the table — so I add this attribute and call it BOOKS.
Finally, I define the ISBN as the ID of the entity. This is done with the javax.persistence.@Id annotation.
Let’s see the whole modified entity:
@Entity
@Table(name = "BOOKS")
public class Book {
@Id
private String isbn;
private String title;
private String author;
// other parts stayed the same so I omit them here
}
The configuration
The configuration file needs one modification: I have to change the mapping tag at the very end from using resource to class and provide the qualified name of the mapped class:
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">org.h2.Driver</property>
<property name="connection.url">jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE</property>
<property name="connection.username">sa</property>
<property name="connection.password"/>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.H2Dialect</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">create</property>
<!-- The mapping information of entities -->
<mapping class="hibernate_example.Book"/>
</session-factory>
</hibernate-configuration>
The mapping file
The mapping file can be deleted because it is not used by Hibernate anymore.
Extending the entity
I mentioned earlier that adding a Date field is a bit complex because mapping dates are not so trivial action. For this, I need a javax.persistence.@Temporal annotation on the field to tell Hibernate that I want to store a date in the database — and I want a date back when I read the information. The javax.persistence.TemporalType tells what kind of information I want to store. Now it is a date.
@Temporal(TemporalType.DATE)
private Date published;
This makes clear for other developers reading your code that the field published is mapped as a Date type between the application and the database.
For the XML configuration I would have to use this configuration:
<property name="date" type="date" />
Running the application
The application can be run as in the last article too and it results in the same output.
Conclusion
Hibernate can utilize a set of standard annotations to eliminate the need of mapping XML files. And with the use of the standard javax.persistence annotations you could switch from Hibernate to another ORM solution implementing the standard interface.
However, some developers are speaking nowadays about “Annotation-Hell” because you can configure almost anything with annotations and sometimes this makes readability of your application bad.
In the next article, I will show you how you can model relations between entities with Hibernate.
Code Download
You can download chapter specific code from Github Here.