Now that you've learned how to set up your first Hibernate Java project it's time to put that fresh new configuration to work!
What You'll Learn
The focus of this podcast / blog post is to teach you how to create the connection between your Java objects and the SQL Database tables. Remember, the whole point of the Hibernate framework is for you to be able to write Java code that allows you to communicate with your database.
When I say that the goal is to communicate with your database, what I mean is:
- Create the tables (if they're not already there) that will represent your Java objects
- Give Java the ability to send queries and execute scripts on your database
- Establish a transactional means by which to perform CRUD operations
What we're going to be tackling in this post will the step #1, how to get Hibernate to create our tables for us.
How to get Hibernate to Create a Table
So the key to getting Hibernate to create a table for us is to understand how Hibernate makes the decision to create a table. It works by scanning a particular package that you've specified in your configuration file (via sessionFactory.setPackagesToScan()
. Hibernate will scan that package for any Java objects annotated with the @Entity
annotation. If it finds any, then it will begin the process of looking through that particular Java object to recreate it as a table in your database!
Before Hibernate will start it's scan, not only do we need to invoke the sessionFactory.setPackagesToScan
code, but we also need to enable the scanning process that the Spring framework handles. We'll need to make a quick tweak in our applicationConfig.xml
file. Take a look at mine here:
The magic line of code above is the <context:component-scan base-package="com.howtoprogramwithjava.example">
line. This is what Spring uses to know where to scan for annotations related to both the Spring framework and the Hibernate framework.
Unfortunately that's not the only step (if only it were that easy!). We still need to specify a couple of things:
- The primary key for the table
- How to generate the primary keys
For both items above, we'll use annotations.
The first annotation (@Id
) is simple and it's used to “mark” the primary key for the table, the second annotation is @GeneratedValue
and it will be used to specify HOW to generate primary keys. Let's take a look at an actual example of all these annotations in action:
import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Table(name="address_book") @Entity public class AddressBook { private Long id; private String name; private String phoneNumber; private String streetAddress; private String zipCode; private String city; private String region; private String country; @Id @GeneratedValue(strategy=GenerationType.AUTO) 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; } @Column(name="phone_number") public String getPhoneNumber() { return phoneNumber; } public void setPhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; } @Column(name="street_address") public String getStreetAddress() { return streetAddress; } public void setStreetAddress(String streetAddress) { this.streetAddress = streetAddress; } @Column(name="zip_code") public String getZipCode() { return zipCode; } public void setZipCode(String zipCode) { this.zipCode = zipCode; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getRegion() { return region; } public void setRegion(String region) { this.region = region; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } }
As you can see above, the @Entity
annotation is used at the class level, but the @Id
and @GeneratedValue
annotations are used at the method level.
It's important to note the exact location of the @Id
and @GeneratedValue
annotations: just above the getter method for the id
instance variable. If you were to put these annotations on the setter method, it won't work as Hibernate only looks at the getter methods for these annotations.
Final Touches
The last thing I should mention is the naming convention for tables and columns with Hibernate. By default Hibernate doesn't know how to insert underscores (_) into the names of tables and columns. So we'll need to help Hibernate out by telling it how we want to name our tables and columns.
When we have any tables or columns names that are more than one word in length, we'll need to use one of two annotations:
@Table(name="")
@Column(name="")
For table names, just use the @Table
annotation and specify the actual name that you'd like to use for the table inside of it. This annotation should only be used at the class level.
For column names, just use the @Column
annotation and specify the actual column name that you'd like to use inside of it. This annotation should only be used at method level (again, just above the getter method).
For those of you who want to see this entire process in action, just check out the video below which will take you step by step through everything you've just learned: