java - 我在获取外部对象时遇到 LazyInitializationException

标签 java hibernate object orm

我正在将 Hibernate 4 用于 Java 项目。

我有下一个包含两个实体的方案:

Units *has many* Users

因此,单位拥有用户的外键(请参阅 table definition )。

当我加载用户时,我可以获得它所属的Unity,但反之则不然。
当我加载 Unity 时,我在尝试获取 User 时遇到异常:

    GenericDao dao = (GenericDao)new UnitsDaoImpl();

    Units unity = (Units)dao.get(1); // user.ID => 1

    Users user = unity.getUsers(); 

    System.out.println(user); // Exception in thread "main" org.hibernate.LazyInitializationException: could not initialize proxy - no Session

查看完整异常here .

调用的dao方法是这个:

@Override
public T get(PK id) {
    T object;

    Session session = HibernateUtil.getSessionFactory().openSession();
    object = (T) session.get(getType(), id);
    session.close();

    return object;
}

如果你想重现它,I have uploaded the code到 GitHub。我正在运行 JDK 8。我读过 other posts但我不知道如何在这里应用解决方案。

<小时/>

注意:上述方法不处理事务,但我尝试了下一个方法,并且得到了相同的结果:

    UnitsDao dao = (UnitsDao)new UnitsDaoImpl();
    List<Units> unity = (List<Units>)dao.fetchAll();
    Users user = unity.get(0).getUsers();
    System.out.println(user); // Exception in thread "main" 

以及 dao 方法:

@Override
public List<Units> fetchAll() {
    List resultList;
    String hql = "FROM Units";

    Session session = HibernateUtil.getSessionFactory().openSession();
    session.beginTransaction();

    resultList = session.createQuery(hql).list();

    session.getTransaction().commit();
    session.close();

    return resultList;
}

最佳答案

好的,问题是您已经在此处关闭了 Hibernate session :

session.close();

当您调用 getUsers() 时,会延迟加载相关用户的集合。但是,这只能在 Activity 的 Hibernate session (您没有)中完成。

对于延迟加载,BalusC 和 Pascal Thivent 提供了一些不错的答案:

What is lazy loading in Hibernate?

在单个 DAO 方法中打开和关闭 session 从来都不是一个好主意。最好在上面的层(通常称为业务/服务层)中执行此操作。

将您的 DAO 类更改为:

public class UnitsDaoImpl implements UnitsDao {

    private Session session;

    public UnitsDaoImpl(final Session session) {
        this.session = session;
    }

    @Override
    public List<Units> fetchAll() {

        return session.createQuery("FROM Units").list();
    }
    // Other methods...
}

将您的调用代码更改为:

Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();

UnitsDao dao = (UnitsDao)new UnitsDaoImpl(session);
List<Units> unity = (List<Units>)dao.fetchAll();
Users user = unity.get(0).getUsers();
System.out.println(user);

session.getTransaction().commit();
session.close();

关于java - 我在获取外部对象时遇到 LazyInitializationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23417711/

相关文章:

java - 我应该将测试方法放在单独的类中吗?如果是这样,怎么办?

java - 我们可以在 @HystrixCommand 上使用 @Async

java - 如何在 Java 中创建 Web 服务(使用 Eclipse)

hibernate - 具有超过 1 个继承级别的 @MappedSuperclass 在实体映射中抛出重复列异常

java - org.hibernate.AnnotationException : Use of @OneToMany or @ManyToMany targeting an unmapped class

javascript - 以不同的方式调用 javascript 函数

Java正则表达式解析/robots.txt

c++ - 具有自定义数据结构的 C++ 中的运算符<<

java - java中如何动态创建数据对象?

java - Hibernate 3 Composite key one with GeneratedValue