Hibernate @OneToMany Bidirectional Relationship

by Trevor Page on July 28, 2014

Java-PodcastSince we’ve already learned about the unidirectional @ManyToOne relationship, we can now move on to talking about what a bidirectional relationship is like, when using Hibernate.

The term “bidirectional” literally means “functioning in two directions”, which is the concept that we will apply in our relationships between two Java objects. When we have a bidirectional relationship between objects, it means that we are able to access Object A from Object B, and Object B from Object A.

We can apply this logic to our real world coding example that we saw in the last post. The example we will use is the relationship between an Employer and an Employee. Previously, we only defined a unidirectional relationship, so we could only access the Employer from the Employee object and not vice-versa.

Now let’s take a look at how to transform our existing unidirectional relationship into a bidirectional one.

Bidirectional @OneToMany Relationship – Employer/Employee

The first step in transforming our unidirectional relationship into a bidirectional relationship is to add the missing reference from the Employer to the Employee.

One critical thing to remember here is that there’s a difference between a reference from the One-to-Many side and the Many-to-One side.

When you traverse from the “Many” side to the “One” side, you only need to make reference to one object, which is why the Employee class holds a single reference to an Employer class via the private Employer employer instance variable.

However, when you traverse from the “One” to the “Many” side, you will need to hold a reference to MANY objects.

Does that make sense? Many-to-One equals one reference, One-to-Many equals many references.

So what will this look like? Well, it means that the Employer will need to hold many references to its Employees, and we accomplish this by storing them as a Collection.

In this example I will use a Set of Employee objects in my Employer class file like so:

Employer.java

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Employer
{
	private Long id;
	private String employerName;
	private Set employees;
	
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	public Long getId()
	{
		return id;
	}
	public void setId(Long id)
	{
		this.id = id;
	}
	public String getEmployerName()
	{
		return employerName;
	}
	public void setEmployerName(String employerName)
	{
		this.employerName = employerName;
	}
	
	@OneToMany(cascade=CascadeType.ALL, mappedBy="employer")
	public Set getEmployees()
	{
		return employees;
	}
	public void setEmployees(Set employees)
	{
		this.employees = employees;
	}
}

What you may have also noticed was that we added the @OneToMany annotation to the getEmployees() method. This is needed so that Hibernate understands that this is the second part of the relationship/link between the Employer and Employee.

So just like we have the @ManyToOne annotation in the Employee class, we also have the @OneToMany annotation in the Employer class… you see? Bidirectional!

Now, I haven’t yet explained what that pesky mappedBy="employer" means…

Using the mappedBy Property on Bidirectional One-to-Many Relationship

The funny thing is that you don’t actually need to use the mappedBy property, but your database will be quite a mess if you don’t.

So I like to say that it’s mandatory to use the mappedBy property when creating a bidirectional relationship in Hibernate. And yes, I did mean to refer to ALL bidirectional relationships with that previous statement.

The mappedBy property is what we use to tell Hibernate which variable we are using to represent the parent class in our child class.

If you were to look at the class definition for the child class (Employee) you will see that we have declared an instance variable called employer, which is what we used to establish our relationship. All we are doing here is we are telling the Employer class which variable the Employee class is using to create the relationship.

So! Since we declared the Employer variable with the name employer, this is what we need to put in the mappedBy property of the @OneToMany annotation.

For those of you who haven’t already seen it, here’s what the Employee class looks like (note that we haven’t made any changes to this class when we had initially created our unidirectional relationship in the last post):

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;

@Entity
public class Employee
{
	private Long id;
	private String employeeName;
	private Employer employer;
	
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	public Long getId()
	{
		return id;
	}
	public void setId(Long id)
	{
		this.id = id;
	}
	public String getEmployeeName()
	{
		return employeeName;
	}
	public void setEmployeeName(String employeeName)
	{
		this.employeeName = employeeName;
	}
	@ManyToOne(cascade=CascadeType.ALL)
	public Employer getEmployer()
	{
		return employer;
	}
	public void setEmployer(Employer employer)
	{
		this.employer = employer;
	}
}

Putting our Bidirectional Relationship to Use

Okay, so now that we’ve created the blueprint for our bidirectional relationship, now we need to put in the supporting code to actually test this stuff out!

In the previous post we had created an EmployeeDao object which we used to save our employee1 and employee2 objects into the database in a unidirectional manner… but… now that we’ve changed our code around to use a bidirectional relationship, we need to change the way we persist our data.

As I mentioned, we previously used the EmployeeDao to persist our data, but now that we’ve switched to bidirectional we will need to use an EmployerDao to carry out our wishes! The EmployerDao will be identical to the EmployeeDao except that it will persist an Employer object. Here’s what it looks like:

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.howtoprogramwithjava.example.persistence.Employer;

@Transactional
@Repository
public class EmployerDao
{
  @Autowired
  SessionFactory sessionFactory;
  
  public void save (Employer employer)
  {
  	Session session = sessionFactory.getCurrentSession();
  	
  	session.save(employer);
  }
	
}

Now the only missing piece is to show you how to actually persist data using this new bidirectional One-to-Many mapping.

I’ve set up the test code in a Controller class, I’ll include all of the code for the sake of completion, but all you really need to be concerned with is how the code inside the test method works.

import java.util.HashSet;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;

import com.howtoprogramwithjava.example.dao.EmployerDao;
import com.howtoprogramwithjava.example.persistence.Employee;
import com.howtoprogramwithjava.example.persistence.Employer;

@Controller
public class HomeController
{
  @Autowired
  EmployerDao employerDao;
  
	@RequestMapping("test")
	public String test (ModelMap model)
	{
		Employer employer = new Employer();
		employer.setEmployerName("Employer 1");
		
		Set employees = new HashSet();
		
		Employee employee1 = new Employee();
		employee1.setEmployeeName("Trevor Page");
		employee1.setEmployer(employer);
		employees.add(employee1);
		
		Employee employee2 = new Employee();
		employee2.setEmployeeName("John Doe");
		employee2.setEmployer(employer);
		employees.add(employee2);
		
		employer.setEmployees(employees);
		
		employerDao.save(employer);

		return "testPage";
	}
}

Inside of the test method is where all the magic happens.

What you need to know is that since we have a bidirectional relationship, this means we need to assign objects to EACH side of the relationship. This means that we need to populate both the employee.setEmployer() as well as the employer.setEmployees(). It’s absolutely critical that this be done correctly.

To persist all the objects correctly you’ll need to follow these generic steps:

  1. Instantiate/Load parent object
  2. Instantiate/Load child objects
  3. Set the parent object in the child objects
  4. Create a collection of child objects
  5. Set the collection of child objects on the parent
  6. Save the parent

Note: To observe best coding practices, the code I’ve put into this Controller class is usually best placed in a Service class, but to keep things as simple as possible for this tutorial I’ve just placed all the code directly into the Controller.

Alright! We’re done! You now know how to create a One-to-Many bidirectional relationship with Hibernate. Congrats!

As always, if you want to be on the cutting edge of these Java tutorials and receive updates on when I’m putting on free webinars and doing give-aways please join my mailing list by putting in your email address in the popup below. When you do you’ll instantly receive one free gift from me (and plenty more in the future). I look forward to seeing you again soon!

{ 3 comments }

Hibernate @ManyToOne Unidirectional Tutorial

by Trevor Page on July 23, 2014

Java-PodcastIn the past we have learned about database relationships, specifically the One-to-Many as well as the Many-to-Many and One-to-One and that was all good, great and grand…

But now I want to talk about how to create those same relationships inside of Hibernate.

Specifically, I want to focus on the One-to-Many relationship in Hibernate and how we go about mapping it out in our Java objects.

But before we do, a word on unidirectional and bidirectional relationships.

Unidirectional vs Bidirectional

In Hibernate, it’s possible to map all three relationships that are available in a standard database, these include:

  • One-to-One
  • One-to-Many
  • Many-to-Many

But what Hibernate also includes is the ability to make EACH of those relationships either unidirectional or bidirectional.

This means that we can have a unidirectional One-to-One and a bidirectional One-to-One mapping, as well as a unidirectional One-to-Many and a bidirectional One-to-Many, as well as a unidirectional Many-to-Many and a bidirectional Many-to-Many relationship.

That’s a lot of relationships!

So what exactly are unidirectional and bidirectional relationships?

It all comes down to Java objects.

Let’s say for example that we have a One-to-Many relationship between Employer and Employee. For any one Employer there can be Many Employees and for any given Employee there can be only one Employer.

If we convert the statement above into Java objects, here’s what that would look like:

Employer.java

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Employer
{
	private Long id;
	private String employerName;
	
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	public Long getId()
	{
		return id;
	}
	public void setId(Long id)
	{
		this.id = id;
	}
	public String getEmployerName()
	{
		return employerName;
	}
	public void setEmployerName(String employerName)
	{
		this.employerName = employerName;
	}
}

Employee.java

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Employee
{
	private Long id;
	private String employeeName;
	private Employer employer;
	
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	public Long getId()
	{
		return id;
	}
	public void setId(Long id)
	{
		this.id = id;
	}
	public String getEmployeeName()
	{
		return employeeName;
	}
	public void setEmployeeName(String employeeName)
	{
		this.employeeName = employeeName;
	}
	
	public Employer getEmployer()
	{
		return employer;
	}
	public void setEmployer(Employer employer)
	{
		this.employer = employer;
	}
}

Okay, so, now we have two Java objects which are enabled as Hibernate Entity objects (via the @Entity annotation). Plus we’ve got all the appropriate mappings for the columns (i.e. @Id and @GeneratedValue for the primary keys).

Also you should note that there’s one key difference between these two objects… the Employee object defines the instance variable private Employer employer as well as the appropriate getters and setters.

This is the key to mapping out a unidirectional relationship.

If we were to instantiate an instance of both of these objects we would be able to determine which Employer an Employee works for (via employee.getEmployer()) but we wouldn’t be able to determine which Employees work for a given Employer (as we have no employer.getEmployees() method).

This is the meaning of a unidirectional relationship. We can only “look” at the relationship in one way.

Now, if we wanted to make this relationship a bidirectional one, we would need to add the aforementioned employer.getEmployees() method… but I don’t want to focus on bidirectional relationships just yet.

Parent and Child Tables

Alright, so you have an idea of the difference between a unidirectional and bidirectional relationship. The reason why it’s important to understand the difference between the two is because it affects the way we will map out our code.

Given that we’re focusing on the unidirectional aspect of the relationship, this means that we are only concerned with mapping the Employer instance variable within the Employee object.

As with all Hibernate related functionality, we will need to use an annotation to tell Hibernate how we’d like to map out our relationship.

But before I discuss those details we need to figure out one last concept… parent and child tables.

With a One-to-Many relationship, the child table is the one that houses the foreign key. So in our example, the foreign key will be placed into the Employee table. This is just the way it works with a One-to-Many relationship, the foreign key is always in the “Many” side of the relationship.

Now that we’ve isolated which is the child table (employee) and which is the parent table (employer) we can go a little deeper into the Hibernate mapping annotations.

@OneToMany vs @ManyToOne

Note that there are two different annotations for mapping a One-to-Many relationship in Hibernate:

  • @OneToMany
  • @ManyToOne

The reason that there are two different annotations is that we need to be able to tell Hibernate which object is the child/many part of the relationship and which object is the parent/one side of the relationship.

We are able to tell Hibernate which object is the parent object by assigning the @OneToMany annotation to the appropriate getter method… and of course we are able to tell Hibernate which object is the child object by assigning the @ManyToOne annotation to the appropriate getter method.

Now, keeping in mind that we’re only concerned with the unidirectional relationship at the moment, I need to let you in on a secret. To properly map a unidirectional One-to-Many relationship, you only need to use the @ManyToOne annotation. This may seem a bit counter-intuitive, but that’s how Hibernate works. You need to map the child/many side of the relationship and only the child/many side.

This fact works nicely with the example classes that I’ve outlined above, let’s take a look at what changes we’ll need to make to the child class (Employee) in order to enable Hibernate’s relationship functionality:

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;

@Entity
public class Employee
{
	private Long id;
	private String employeeName;
	private Employer employer;
	
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	public Long getId()
	{
		return id;
	}
	public void setId(Long id)
	{
		this.id = id;
	}
	public String getEmployeeName()
	{
		return employeeName;
	}
	public void setEmployeeName(String employeeName)
	{
		this.employeeName = employeeName;
	}

    // HERE IS THE NEW ANNOTATION CODE WE'VE ADDED
    @ManyToOne(cascade=CascadeType.ALL)
	public Employer getEmployer()
	{
		return employer;
	}
	public void setEmployer(Employer employer)
	{
		this.employer = employer;
	}
}

You’ll notice that all the code is the same except for the addition of the @ManyToOne annotation.

We place this annotation at the method level on the getter method for the object that we’d like to join with. Since we’re joining to the Employer class, we put the annotation above the getEmployer() method.

One other thing to note is the cascade that we have assigned inside the annotation.

Cascades in Hibernate

The concept of cascading is pretty straight-forward and it deals with keeping the data in a nice organized state.

Let’s say for example that we have inserted a couple of employers and three employees into our database. It might look something like this:

Employer Table
id employer_name
1 Employer 1
2 Employer 2
Employee Table
id employee_name employer_id
1 Trevor Page 1
2 John Doe 1
3 Jane Doe 2

Here we have two employees who are assigned to Employer 1, and one employee who is assigned to Employer 2.

What would happen if Employer 1 went out of business? All of the employees would likely be let go and wouldn’t work at Employer 1 anymore. This is a fact that can be automatically “handled” by Hibernate. It’s called a cascade delete.

When someone deletes Employer 1, Hibernate can be told (via cascading rules) to automatically delete any child rows that point to Employer 1. So when Employer 1 is delete, so will the employees “Trevor Page” and “John Doe” as they are associated with Employer 1.

The same concept is applied to inserting new values into the database via Hibernate.

In the example code above, we only assign a relationship to the child object via the @ManyToOne() annotation. This means that if we perform an insert on the child row, Hibernate will automatically create the parent row based on where the child row is pointing.

Let’s take a look at this as a Java example. I’ve gone ahead and created a basic Controller that will perform the insertion of the records:

@Controller
public class HomeController
{
  @Autowired
  EmployeeDao employeeDao;
  
	@RequestMapping("test")
	public String test (ModelMap model)
	{
		Employer employer = new Employer();
		employer.setEmployerName("Employer 1");
		
		Employee employee1 = new Employee();
		employee1.setEmployeeName("Trevor Page");
		employee1.setEmployer(employer);
		
		Employee employee2 = new Employee();
		employee2.setEmployeeName("John Doe");
		employee2.setEmployer(employer);
		
	  employeeDao.save(employee1);	
	  employeeDao.save(employee2);
		return "testPage";
	}
}

The main things to concern yourself with in the code above is everything inside of the test() method. I’ve included all of this code for the sake of completion, but I don’t want you to get bogged down in the details outside of the test method.

The important things to note in the code above are that we’re actually creating Java objects just like we would if we weren’t using Hibernate. We instantiate instances of the Employer object as well as two Employee objects. After setting the names of both the employer and employees, we take one critical step in this process… we set the instance of the Employer object inside of each of the Employee objects.

The process of assigning the employer to the employees is critical, and if you think about it, it makes sense. We do the same thing in the database table right? We have an employer_id column inside of the employee table! So we’re really just mimicking the database layout inside of our Java code… easy peasy!

Once we have done this, we invoke the save() method on the EmployeeDao object for each of our Employee objects. So the question is, what does the employeeDao.save() method do? I’ll show you:

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.howtoprogramwithjava.example.persistence.Employee;

@Transactional
@Repository
public class EmployeeDao
{
  @Autowired
  SessionFactory sessionFactory;
  
  public void save (Employee employee)
  {
  	Session session = sessionFactory.getCurrentSession();
  	
  	session.save(employee);
  }
	
}

All the EmployeeDao does is just grab the session and save the object.

Once this session.save(employee) method is invoked, this is where hibernate will try to insert the actual employee into the database. It will realize that there’s a relationship set and will also realize that the parent row hasn’t been inserted yet, so it will first insert the parent “employer” row, then it will insert the child “employee” row as expected.

If the appropriate “employer” row already exists in the database, then it will just insert the child row and assign the appropriate foreign key to the child row.

Done and done! So there you have it, you now know how to create a One-to-many relationship with the Hibernate framework and actually create and insert the data via Java code. Very powerful stuff.

As always, if you want to be on the cutting edge of these Java tutorials and receive updates on when I’m putting on free webinars and doing give-aways please join my mailing list by putting in your email address in the popup below. When you do you’ll instantly receive one free gift from me (and plenty more in the future). I look forward to seeing you again soon!

{ 0 comments }

Hibernate – Creating Data Access Objects (DAOs)

by Trevor Page on July 15, 2014

Java-Podcast

Data Access Objects – What are they?

Data Access Objects (or DAOs for short) are used as a direct line of connection and communication with our database. DAOs are used when the actual CRUD (CRUD = Create, Read, Update, Delete) operations are needed and invoked in our Java code. These data access objects also represent the “data layer” of our application.

These objects are still just plain old Java objects that incorporate the use of some Hibernate annotations to give them the functionality we need from them. Again, that functionality being the communication with the database.

Also, believe it or not, the concept of creating a file specifically for accessing the database is a design pattern. It’s called the Data Access Object Pattern and you can read more about it from this nice short Wiki article.

What Hibernate Annotations Should We Use?

Okay, so now that you’re somewhat familiar with DAOs, it’s time to learn how to integrate these plain old Java objects with our Hibernate framework (so they actually do the work we need them to do).

There are two main annotations that you need to be familiar with:

  • @Repository
  • @Transactional

The first of the two annotations @Repository is one from Spring and it’s pretty straight-forward. It’s used to mark the Java file as something Spring calls a “Component”, which enables it to be scanned and incorporated into Spring’s code. You really just need to remember to put this annotation in all of your DAOs (on the class level) and you’ll be good to go.

The second (and more complicated) annotation is the @Transactional annotation. This annotation is used as a means to enable transaction management within your Java DAO file.

Transaction management is a vast (and complex) topic. I’ll give you a brief overview of what it is and why it’s useful.

Transaction management is all about data integrity… which means it’s all about keeping your data valid, non-corrupt and error free: three things that are very handy! Let’s think of the opposite scenario, having our data be invalid, corrupt and full of errors… does that last sentence make you wince? Well, if it does, then transaction management is the vaccine you need.

What is a Transaction?

A transaction (as it pertains to databases) is the trick we use to be able to roll back (or revert) a database operation. Consider the following database operation:

insert into users (username, password) values ('trevor_page', 'password**!');

This database operation has to do a few things:

  1. Insert a new row of data into the users table
  2. Assign a primary key to this new row
  3. Populate the new row with the provided data

Fairly straight forward stuff, but what happens if your database server crashed after step #1? Or what happens if someone yanks the power cord out of the server by accident after step #1? What happens if the disk drive becomes full after step #2?

All of these scenarios would leave the database operation only “partly committed”. If we were to leave the data as is, in its partially committed state, then our data would be corrupt and could lead to errors in our application. NOT COOL!

Okay, so now let’s consider what I’ve said about a database transaction. Its job is to “roll back” the database operation if it doesn’t complete correctly. So let’s assume that we open a transaction, start our database operation, get to step #2 and then there’s a failure. The database keeps track of the “state” its in and (once restored) sees that there’s a transaction that was not fully committed, so it will roll back to the previously known “stable state”… thus eliminating the partially committed (and invalid) data.

Magic!

So you see why transactions are so useful? They will save your butt when the unexpected becomes a reality… now there’s a whole lot more to understand about transactions, but that’s outside of the scope of this conversation, so I’ll get back to the topic at hand.

Example of a Real Data Access Object in Java

Okay, so now it’s time for the big reveal! Let’s take a look at an example DAO class that I’ve created.

We’ve been talking about using the example of an Address Book program, so let’s take a look at what the beginning of our Address Book DAO would look like:

import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

@Repository
@Transactional
public class AddressBookDao
{
  // empty class... for now!
}

As you can see above, we have put both of the annotations that we’ve just learned about at the class level for the DAO.

Pretty straight forward right?

Now let’s talk about the SessionFactory

What the heck is a SessionFactory?

A SessionFactory is what we use to grab individual Sessions so that we can talk to our database. It uses the Factory design pattern, which essentially means it’s sole purpose is to dish our Sessions whenever you ask for them.

So the real question here is, what the heck is a Session?!

A Session is what we use to create open our initial transaction, perform some kind of database operation, and then commit the transaction (or roll it back if there was a failure).

Let’s take a look at how we get a Session in Java:

import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

@Repository
@Transactional
public class AddressBookDao
{
  @Autowired
  SessionFactory sessionFactory;
  
  /**
   * Save an AddressBook object to the database
   */
  public void save(AddressBook addressBook)
  {
  	Session currentSession = sessionFactory.getCurrentSession();
  	currentSession.saveOrUpdate(addressBook);
  }
}

Now things are starting to get a little more interesting!

You see that we used the @Autowired annotation to automatically populate the sessionFactory with an actual real instantiated instance. Spring can do this because we’ve already configured the SessionFactory in our PersistenceConfig class. If you don’t remember what that file is, you can read about it in this post.

Once we have a real instance of the SessionFactory we can use it to grab a real Session. We do so by invoking the getCurrentSession() method and assign it to a variable.

Now that we have a Session we can invoke one of our CRUD operations. In the example above, I am invoking a saveOrUpdate(), which will either create a new row of data or update an existing row.

Hibernate’s saveOrUpdate Method

This is a very important method to understand, as it incorporates one of the fundamental rules by which Hibernate operates.

You see, how the heck is Hibernate supposed to know whether or not you wish to create a new row of data with the object you’ve given to it, or if it should update an existing row of data?

Let’s assume you’ve created a brand new AddressBook object and populated it with some relevant information. Now you wish to save it to the database… YOU know that it’s a new piece of data, and therefore it should have a new row created in the database… but how does Hibernate know?

Hibernate looks at the @Id variable that you’ve defined in the AddressBook class! If there’s an actual ID value assigned to your object, then that means it must already exist in the database and therefore this operation should be an UPDATE… if there’s no ID valued populated in the AddressBook object (i.e. it’s null), then it should be a new row and it performs an INSERT.

So let’s say we have the following AddressBook scenario:

AddressBook ab = new AddressBook();
ab.setId(1L);
ab.setCity("Toronto");
ab.setCountry("Canada");
ab.setEmailAddress("trevor@javavideotutorials.net");
ab.setName("Trevor Page");
ab.setPhoneNumber("555-555-1234");
ab.setRegion("Ontario");
ab.setStreetAddress("123 Fake St");
ab.setZipCode("M1M 3M2);
addressBookDao.save(ab);

What do you think will happen when we invoke the save(ab) method?

If you look carefully, you’ll see that I’ve assigned a value to the ID field… so given my explanation above, that means that Hibernate will perform an UPDATE.

Now, what happens if we get rid of the line of code that assigns the ID?

AddressBook ab = new AddressBook();
//ab.setId(1L);
ab.setCity("Toronto");
ab.setCountry("Canada");
ab.setEmailAddress("trevor@javavideotutorials.net");
ab.setName("Trevor Page");
ab.setPhoneNumber("555-555-1234");
ab.setRegion("Ontario");
ab.setStreetAddress("123 Fake St");
ab.setZipCode("M1M 3M2);
addressBookDao.save(ab);

Now when we run the save(ab) method, hibernate sees that there’s no ID set, so it will perform an INSERT.

The functionality described above is critical to understand!

How do we Read from the Database with Hibernate?

Another great question, here we will make use of something called Criteria. Criteria is the object that we will use to create SQL queries in Java… if you like you can also create native SQL queries with Hibernate, but it’s actually a LOT easier to use Criterias.

In the example below, you will see how we create the Criteria to search the address_book table for the name that we will pass in:

public List getAddressBookByName (String name)
{
  	Session currentSession = sessionFactory.getCurrentSession();
  	
  	List list = currentSession.createCriteria(AddressBook.class)
                             .add(Restrictions.eq("name", name))
                             .list();
  	return list;
}

We use a Session to create the Criteria and we add Restrictions to filter our results.

To illustrate how this works, let’s assume we just use this Criteria:

List list = currentSession.createCriteria(AddressBook.class).list();

This will create the following SQL query:

select * from address_book;

This is a very broad search, and thus we need to add a filter on it to make it more narrow. Remember that our current mission is to retrieve a particular person’s address information. We do this by adding Restrictions, and in our example we restrict the broad results by searching for a name.

We then invoke the list() method which will actually execute the query and return a list of results. If there are no matching entries then it will be an empty list, if there are one or more entries, then they will be populated in our list.

Easy peasy.

There is lots more we can do with the Criteria object in Hibernate, such as grouping and ordering our data… but that’s a topic for discussion later.

How do we Delete Rows from the Database?

Our final topic will be about deleting rows.

The only thing you need to know here is that you actually need to LOAD the row from the database before you can delete it. This is something built into the Hibernate framework and it’s another concept that is important to understand. If you simply just create your own object manually and then pass it in to a delete method, hibernate won’t be able to carry out the operation as the object you’ve asked to be deleted is “detached”.

There’s some great information on the “state” of objects as they pertain to the Hibernate framework in this tutorial from JBoss. It’s a bit of a heavy read, but it’s definitely good to understand how this stuff works.

In any case, the point here is that you need to make sure the object that you wish to delete is the actual persistent version of the object. So this means you’ll need to first load the object from the database before invoking the delete. Here’s how to do it:

public void deleteById (Long id)
  {
  	Session currentSession = sessionFactory.getCurrentSession();
  	
  	AddressBook result = (AddressBook) currentSession.createCriteria(AddressBook.class)
                             .add(Restrictions.idEq(id))
                             .uniqueResult();
  	
  	if (result != null)
  	{
  		currentSession.delete(result);
  	}
  }

The only curve-ball in this code is the use of the uniqueResult() method. Previously when we read data from the database, we used the list() method to invoke our query, but here we have a slightly different scenario. We are loading the object by the ID, so we know there is only going to be ONE result back from the database… since we know we are only getting one object back, we can ask for a uniqueResult as opposed to getting list.

And that’s really all there is to it in the simple cases.

You now know how to Create, Read, Update and Delete data using Hibernate! Congrats!

If you liked this tutorial, I’d highly recommend jumping on my mailing list. I will keep you up to date with all the need to know information related to Java programming, plus you’ll get access to a list of the top 7 tools that Java professionals use every day, as well as invitations to all of my free webinars that I host where I sit down with you and teach important subjects in the Java world.

To join the mailing list just fill out your email in the popup below or navigate to this sign up page!

{ 1 comment }

Hibernate @Entity – Mapping Your Java Beans

by Trevor Page on July 8, 2014

Java-PodcastNow 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:

  1. Create the tables (if they’re not already there) that will represent your Java objects
  2. Give Java the ability to send queries and execute scripts on your database
  3. 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:

  1. The primary key for the table
  2. 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:

  1. @Table(name="")
  2. @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:

{ 0 comments }

Hibernate Persistence for Beginners

by Trevor Page on July 3, 2014

Java-PodcastLadies and Gentlemen! We have finally hit a milestone in our journey of learning Java, we are now done talking specifically about SQL and are moving on to talk about persistence frameworks.

Let’s start with the most obvious question first…

What is a Persistence Framework?

As the name implies, it has something to do with persisting things… this means that we’re still talking about databases. But what is it that we are persisting with this framework?

Objects (of course)

A persistence framework is something we use in Java to bridge the gap between Java and SQL.

Hopefully we’ve gone through all of my previous tutorials and have learned a thing or two about Java and SQL. But one thing I haven’t taught you yet, is how to put your knowledge of SQL into Java.

That’s what I’ll be teaching you throughout these Hibernate (persistence framework) tutorials.

And if you haven’t guessed it already, Hibernate is a persistence framework that you can use in Java. It’s what allows you to write Java code (staying true to Object Oriented programming practices) and yet still be able to communicate with your database. Cool eh?

Why use Hibernate?

Overall, Hibernate is widely adopted and is open source software. This means that you’ll have very readily accessible help documentation across the internet (just like the one you’re reading right now). The more users a particular project/framework has, the more overall support you’ll be able to receive.

Hibernate is no exception to this rule, there are hundreds (if not thousands) of blogs dedicated to Hibernate and Hibernate tutorials.

Not only that, Hibernate is a fairly simple and flexible framework to use when compared to other alternatives out there. You’ll be able to use Hibernate with pretty much any database system you plan on using (including the big ones like MySQL, MS SQL Server, Oracle, PostgreSQL).

Hibernate also integrates and plays nice with the Spring Framework. which is another framework that you’re hopefully already familiar with. If you’re not, then I’d suggest reading up on it.

What you need to know when using Hibernate

There are some pre-requisites for learning Hibernate. I’m going to be progressing through these Hibernate tutorials assuming that you already have at least a beginners grasp on the following languages / technologies:

  1. Java
  2. Spring Framework
  3. SQL

If you don’t already understand the things listed above, then you’re going to have to pause your learning on Hibernate, because you’ll likely get lost in all the details.

If you have a good understanding of those concepts / technologies, then you’re almost good to go. We’ll need to talk a little bit about a technology called Maven before we can continue.

You see, Maven was created by Apache with the goal of simplifying the annoying project management aspect of programming (namely the build process and library management). As a software project grows, you’re more likely to need to depend on 3rd party software / library (like Spring and Hibernate) to get the job done right.

Getting Spring and Hibernate set up correctly and running is actually a VERY annoying and somewhat complex task… especially since there are so many bloody versions of each framework. This is where Maven comes in, it allows you to MUCH more easily point to the version of each framework that you want to use and then “install it”.

Maven uses something called a “project object model” to manage your projects… this is just a fancy way of saying, they have a single XML file where you will specify all the information about what frameworks you’d like your project to use. It’s not too difficult to use once you get used to it.

The goal of these tutorials, however, is not to teach you the ins and outs of Maven, but rather to just show you the basics of what you need to know about Maven to get up and running smoothly with Hibernate (and Spring).

Okay, Let’s Setup Hibernate

The easiest way for me to show you how to go about setting up Hibernate is to do it in a video, so I’ve recorded one and have included it below for your viewing enjoyment!

Please watch the video above for a full explanation of how to set up your project.

Below I’ve included the source code I used to create the two Hibernate specific set up files.

Hibernate Configuration Files

There are two files that you’ll need to create to get the ball rolling with your Hibernate set up.

  1. PersistenceConfig.java
  2. persistence-mysql.properties

Note: The actual names of these files doesn’t actually matter, what matters is that one is a Java file that will be used to configure your Hibernate framework and a properties file.

PersistenceConfig.java

import java.util.Properties;

import javax.sql.DataSource;

import org.apache.tomcat.dbcp.dbcp.BasicDataSource;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableTransactionManagement
@PropertySource({ "classpath:persistence-mysql.properties" })
@ComponentScan({ "com.howtoprogramwithjava.example" })
public class PersistenceConfig
{
	@Autowired
  private Environment env;

  @Bean
  public LocalSessionFactoryBean sessionFactory() {
     LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
     sessionFactory.setDataSource(restDataSource());
     sessionFactory.setPackagesToScan(new String[] { "com.howtoprogramwithjava.example" });
     sessionFactory.setHibernateProperties(hibernateProperties());

     return sessionFactory;
  }

  @Bean
  public DataSource restDataSource() {
     BasicDataSource dataSource = new BasicDataSource();
     dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
     dataSource.setUrl(env.getProperty("jdbc.url"));
     dataSource.setUsername(env.getProperty("jdbc.user"));
     dataSource.setPassword(env.getProperty("jdbc.pass"));

     return dataSource;
  }

  @Bean
  @Autowired
  public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {
     HibernateTransactionManager txManager = new HibernateTransactionManager();
     txManager.setSessionFactory(sessionFactory);

     return txManager;
  }

  @Bean
  public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
     return new PersistenceExceptionTranslationPostProcessor();
  }

  Properties hibernateProperties() {
     return new Properties() {
        {
           setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
           setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
           setProperty("hibernate.globally_quoted_identifiers", "true");
        }
     };
  }
}

persistence-mysql.properties

# jdbc.X
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/YOUR_DATABASE_NAME
jdbc.user=your_database_username
jdbc.pass=your_database_password
 
# hibernate.X
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
hibernate.show_sql=false
hibernate.hbm2ddl.auto=create-drop

If you’re curious as to where you should create these files, you can just watch the video above and you’ll see exactly where they get created.

{ 3 comments }

SQL Subquery

June 25, 2014

Podcast: Play in new window | Download The SQL Subquery Now that you’ve learned about SQL Joins, aggregate functions and the group by keyword, it’s time we moved on to our final topic in our SQL tutorial series. Today you’ll be learning all about SQL Subqueries, how to use them and when you should use […]

Read the full article →

SQL Group By

June 16, 2014

Podcast: Play in new window | Download SQL Group By After having talked about all the SQL Aggregate functions, there’s one more topic that goes hand in hand with what we’ve already learned… The group by keyword. This particular keyword allows us to take a bunch of data and mash it all together into matching […]

Read the full article →

SQL Aggregate Functions

June 5, 2014

Podcast: Play in new window | Download SQL Aggregate Functions In today’s podcast episode (which can be played by clicking the PLAY button above) you’ll be learning all about the aggregate functions that exist in SQL. What the heck is an aggregate function? Well that’s what I’m going to try and teach you today, and […]

Read the full article →

SQL Join

May 28, 2014

Podcast: Play in new window | Download The SQL Join There are three categories of joins that you can make use of in SQL: Inner Join Outer Join Cross Join But before we dive into the categories of joins, we first need to have an understanding of what a join really is. Joins are used […]

Read the full article →

SQL Tutorial

May 23, 2014

Podcast: Play in new window | Download Learn SQL – Enforce Relationships Part II Be sure to listen to the embedded podcast episode that goes along with this blog post. You can click the PLAY button on the player above. In this SQL tutorial episode/post we’re going to learn how to enforce our SQL relationships […]

Read the full article →