Hibernate Configuration and More JPA (Java Persistence API) Annotations
In the Previous tutorial of Hibernate Series, we have seen the concept of saving an object in the database with Hibernate. We have configured Hibernate with our application and database. We have also created an object to store it in the database. Annotations provide hints for Hibernate. Hibernate configuring file provides many important details for Hibernate. On the basis of these details Hibernate decide what to do with the object and how to store it. In this tutorial, we will discuss the Hibernate configuration file in detail.
Query tool in pgAdminIII
Open the Query tool in pgAdminIII and write a query like this. Query tool can be opened by pressing Ctrl+E or by navigating to Tool – – > query tool
1 |
Select * from UserDetails |
By executing the above-mentioned query we can view the table that we have previously created.
hbm2ddl.auto Explanation
To understand hbm2ddl Let’s perform an experiment.
Edit HibernateMain as shown below.
This Line of code in “HibernateMain.java” |
objectUser.setUserId(1); objectUser.setUserName(“UserName”); |
Will be replaced with |
objectUser.setUserId(2); objectUser.setUserName(“SecondUserName”); |
And run the HibernateMain as Java Application this will remove the UserName and insert SecondUserName in the database.
Execute the query in the query tool of pgAdminIII, this will display only one record with value SecondUserName
We have not yet discussed the hbm2ddl in hibernate configuration file when hbm2ddll is set to create this will drop all the tables on each run and recreates it, which can cause the data loss that we have stored in the previous run. We will use update instead of creating the hibernate configuration file. Edit hibernate.cfg.xml as follows
This Line of code in “hibernate.cfg.xml” |
<!– Drop and re-create the database schema on startup –>
<property name=“hbm2ddl.auto”>create</property> |
Will be replaced with |
<!—update the database –>
<property name=“hbm2ddl.auto”>update</property> |
The update will tell Hibernate to update the database only when any changes occur. Again try to run the HibernateMain as Java Application.Now execute the query in the query tool of pgAdminIII, this will display both the records with no data loss.
There is another thing that we have done in hibernate.cfg.xml , we have set show_sql to true this means that we are telling hibernate to print the SQL commands that it is executing in the background to perform our task.
There are some other annotations and their properties that we will look here. @Entity has a property called name we can use it as follows
Override Table Name
@Entity (name=”YourTableNameHere”) comes from javax.persistence.Entity
If we only use @Entity then hibernate will create the table with the name of the class name but when we use name attribute of the @Entity and specify a name in the quotes, this will create a table with the name specified in the string.
Override Column name
@Column (name=”YourColumnNameHere”) comes from javax.persistence.Column
By default hibernate picks the field name as the column names.If we want to restrict hibernate to use our field names as column names of the table. We will use this annotation with the fields, here attribute name is telling hibernate the custom name for the column.
We can also use multiple annotations on the same field, for example, we have a private field of integer type with name id. We want to make this field primary key and we also want to use our custom name to be used for the column name. In this type of scenario, we will use multiple annotations on the same field.
Update first 15 lines of the User Details.java as shown below
1 2 3 4 5 6 7 8 9 10 11 12 13 |
package org.beginnersheap.uzair.dto; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; @Entity (name="NewTableName") public class UserDetails { @Id private int userId; @Column(name="NewColumnName") private String userName; public int getUserId() { return userId; } |
Output of overridden Table and Column Name
In HibernateMain.java update the code to insert third value in the database as shown below
This Line of code in “HibernateMain.java” |
objectUser.setUserId(2); objectUser.setUserName(“SecondUserName “); |
Will be replaced with |
objectUser.setUserId(3); objectUser.setUserName(“ThirdUserName”); |
run the HibernateMain as Java Application this will insert another record in the databse
Hibernate Annotations
Annotations are placed on the top of the field. It can be placed on top of the functions/methods.
@Table (name=”Table Name”)
Package of @Table in hibernate is javax.persistence.Table. There are various attributes of the Table annotation that can be used with it these are
- name
- uniqueConstraints
- appliesTo
- indexes
With this annotation, we can set name for our tables. The difference between the @Entity and @Table will make sense when we write HQL (Hibernate Query Language), we will see the difference when we write HQL.
Example:
Add more member variables in the previous example and generate getters and setters for these member variables
Initialize this property in the Main Class using setters.
Saving of the object part of our previous code remains same
UserDetails.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
package org.beginnersheap.uzair.dto; import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Table; import javax.persistence.Id; @Entity @Table (name="NewTableName") public class UserDetails { @Id private int userId; private String userName; private Date joinedDate; private String Address; private String description; public Date getJoinedDate() { return joinedDate; } public void setJoinedDate(Date joinedDate) { this.joinedDate = joinedDate; } public String getAddress() { return Address; } public void setAddress(String address) { Address = address; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public int getUserId() { return userId; } public void setUserId(int userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } } |
HibernateMain.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
package org.uzair.hibernate; import java.util.Date; import org.beginnersheap.uzair.dto.UserDetails; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateMain { public static void main(String[] args) { UserDetails objectUser = new UserDetails(); objectUser.setUserId(1); objectUser.setUserName("FirstUserName"); objectUser.setAddress("ABCDXYZ"); objectUser.setJoinedDate(new Date()); objectUser.setDescription("a long description here"); SessionFactory factory = new Configuration().configure().buildSessionFactory(); Session session = factory.openSession(); session.beginTransaction(); session.save(objectUser); session.getTransaction().commit(); } } |
hibernate.cfg.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- Database connection settings --> <property name="connection.driver_class">org.postgresql.Driver</property> <property name="connection.url">jdbc:postgresql://localhost:5432/hibernatedb</property> <property name="connection.username">postgres</property> <property name="connection.password">1234poiu</property> <!-- JDBC connection pool (use the built-in) --> <property name="connection.pool_size">1</property> <!-- SQL dialect --> <property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property> <!-- Disable the second-level cache --> <property name="cache.provider_class">org.hibernate.cache.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> <!-- Names the annotated entity class --> <mapping class="org.beginnersheap.uzair.dto.UserDetails"/> </session-factory> </hibernate-configuration> |
TestRun:
Run as java Application, in the console, you can see the following output
1 2 3 4 5 6 7 8 9 10 |
<strong>Hibernate: drop table if exists NewTableName cascade </strong>Sep 10, 2016 8:12:28 PM org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@4409e975] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode. <strong>Hibernate: create table NewTableName (userId int4 not null, Address varchar(255), description varchar(255), joinedDate timestamp, userName varchar(255), primary key (userId)) </strong>Sep 10, 2016 8:12:28 PM org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@312ab28e] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode. Sep 10, 2016 8:12:28 PM org.hibernate.tool.schema.internal.SchemaCreatorImpl applyImportSources INFO: HHH000476: Executing import script 'org.hibernate.tool.schema.internal.exec.ScriptSourceInputNonExistentImpl@278bb07e' <strong>Hibernate: insert into NewTableName (Address, description, joinedDate, userName, userId) values (?, ?, ?, ?, ?) </strong> |
According to the output, Hibernate first drops the table and then creates it again this is because of the hbm2ddl.auto set to create, finally hibernate inserts the record in the table. Hibernate have inserted new columns with the name of fields and with respect to the data types of the fields.In this insert hibernate is mapping the java datatype with the SQL datatypes.
@Basic
Package of @Basic in hibernate is javax.persistence.Basic;
@Basic has two properties that we can make use of, these can be shown in the figure below
fetch attribute is used to tell hibernate to fetch field as lazy or eager
1 |
@Basic (fetch=FetchType.LAZY) |
FetchType is provided in javax.persistence to define how to fetch fields
optional attribute is used to tell hibernate that field is nullable or not.
@Transient
Package of @Transient in hibernate is javax.persistence.Transient;
It is used without properties. If we want to skip the field and want it not to be saved then we use @Transient with that Field. it tells hibernate not to persist that specific field in the database.
@Temporal
Package of @Temporal in hibernate is javax.persistence.Temporal;
Temporal is basically the data which could have the date, time and timestamp in it. @Temporal has following properties that we can make use of, these can be shown in the figure below
TemporalType is provided in javax.persistence.TemporalType to define how to use this field
1 |
@Temporal (TemporalType.DATE) |
@Lob
Package of @Lob in hibernate is javax.persistence.Lob;
It is used without properties. Lob means the large object. We use it to tell hibernate that we are saving Pages of description as a Clob or Blob. Hibernate determine it with our used field type. If we use field type as an array of characters it means Clob and if we use byte stream it means Blob.
Summary:
In this tutorial, we have accomplished following things.
- hbm2ddl.auto Explanation
- JPA – Java Persistence API Annotations Examples
- Various JPA Java Persistence API Annotations
Hope that you like this tutorial. Stay tuned for more upcoming tutorials. Stay Blessed!
About Author: Uzair Ahmed Khan is Technical Content Writer, Computer Software Blogger, and Software Engineer. He has a keen eye on Java Technologies other Related Developments.