我正在使用Hibernate和jpa,我正在尝试使用LazyInizializationException做一个非常简单的事情。我知道LazyInizializationException意味着什么,但我无法理解为什么它以最常见和最简单的方式做所有事情。这是这段关系的“一面”:
@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...
这就是“很多”方面:
@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...
抛出异常的jUnit测试是:
@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();
我按照Hibernate Documentation中的解释建立了这种关系。任何提示?我犯了一些大而愚蠢的错误吗?
答案 0 :(得分:3)
虽然@ Xavi的答案非常合理,但您可能并不总是想为用户加载设备。如果不这样做,有两种方法可以解决这个问题。
我个人使用事务方法,因为它允许更多的灵活性,并允许JPA在需要时延迟加载。有关会话生命周期的更多有趣信息,另请参阅http://community.jboss.org/wiki/OpenSessionInView。
答案 1 :(得分:1)
异常告诉您,当会话关闭时,您正试图获取一些延迟加载的关联元素。当hibernate会话仍处于打开状态时,你应该在dao的方法中调用u.getDev()
或Hibernate.initialize(u.getDev())
。
或者,如果您使用的是Criteria
,则还可以使用setFetchMode
来强制提取。
public User getUser(String id) {
Session session = getSession();
Criteria criteriaQuery = session.createCriteria(User.class);
criteriaQuery.add(Expression.eq("id", id));
criteriaQuery.setFetchMode("dev", FetchMode.JOIN);
return criteriaQuery.uniqueResult();
}
答案 2 :(得分:0)
当您访问关系时,实体可能与会话(事务上下文)分离。尝试将您的测试方法包含在事务中。