Search code examples
javahibernatespringjpa

LazyInitializationException with OneToMany in the simpliest way


I'm using Hibernate with jpa and I'm getting LazyInizializationException trying to do a very simple thing. I know what does LazyInizializationException means but I can't understand why it comes while i'm doing everything in the most common and simple way. This is the "one" side of the relationship:

@Entity
public class User implements Serializable{

@Id @GeneratedValue
private int idUser;

private String name;
private String surname;
private String username;

@OneToMany(mappedBy="user")
private List<Device> dev;

...getters and setters...

and this is the "Many" side:

@Entity
public class Device implements Serializable {

@Id @GeneratedValue
private int idDevice;

private String brand;
private String model;

@ManyToOne
@JoinColumn(name="user_fk")
private User user;

...getters and setters...

the jUnit test that throws the exception is:

@Test
public void testLazyUserSnd() {
    User u = uDao.getUser(2);
    List<Device> devList = u.getDev();
    Device aDevice = devList.get(0); // <--- Here the exception is thrown
    aDevice.getModel();

I made the relationship as explained in the Hibernate Documentation. Any hint? Am I making some big and stupid mistakes?


Solution

  • While @Xavi's answer is perfectly reasonable, you may not always want to load the devices for a user. If you don't, there are 2 ways of fixing this.

    1. Create an additional method uDao.getUserWithDevices(id) and call that when you know you need devices, otherwise call the uDao.getUser(id).
    2. Encapsulate the test method, and therefore any production code that uses the method, in a transaction. In other words keep the session open as long as you need to.

    Personally I'd use the transaction method since as it allows more flexibility and allows JPA to lazy load whenever it needs to. See also http://community.jboss.org/wiki/OpenSessionInView for more interesting information around session lifecycle.