Hibernate,Java:没有关闭会话或会话

时间:2012-01-24 10:12:14

标签: java hibernate session

我已经在Stackoverflow上看到了这种问题,但没有任何东西可以帮助我解决我的问题。

我是Hibernate的新手,有一个用Java和MySQL制作的项目,因此使用hibernate。我设法访问我的数据,修改它们,删除它们,但我阻止了一个方法因为我有一个例外到达..并且看到我理解仍然不是我管理的所有线程都没有删除这个bug:

这是我的错误:

  

org.hibernate.LazyInitializationException    严重:未能懒惰地初始化角色集合:   DAO.User.files,没有关闭会话或会话   org.hibernate.LazyInitializationException:懒得初始化   角色集合:DAO.User.files,没有关闭会话或会话     在   org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358)     在   org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350)     在   org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:343)     在org.hibernate.collection.PersistentSet.add(PersistentSet.java:189)     在DAO.UserDAO.removeGroupAddUserFiles(UserDAO.java:252)at   javaapplication5.JavaApplication5.main(JavaApplication5.java:37)

以下是我的Java类:

public static void main(String[] args) {
        GroupDAO grDAO = new GroupDAO();
        List[] lists = grDAO.removeGroup(grDAO.getGroupById(1));

        FileDAO fiDAO = new FileDAO();
        fiDAO.removeGroupAddFiles(lists);

        UserDAO usDAO = new UserDAO();
        usDAO.removeGroupAddUserFiles(lists);
    }

GroupDAO.java:

public List[] removeGroup(Group group) {
        Set<File> setFiles = group.getFiles();
        Set<User> setUsers = group.getUsers_1();
        List[] lists = new List[2];

        Iterator<File> itFiles = setFiles.iterator();
        Iterator<User> itUsers = setUsers.iterator();
        List<File> listFiles = new ArrayList<File>();
        List<User> listUsers = new ArrayList<User>();
        while (itFiles.hasNext()) {
            listFiles.add(itFiles.next());
        }
        while (itUsers.hasNext()) {
            listUsers.add(itUsers.next());
        }

        lists[0] = listUsers;
        lists[1] = listFiles;

        org.hibernate.Transaction tx = session.beginTransaction();
        session.delete(group);
        tx.commit();

        return lists;
    }

FileDAO.java:

public List[] removeGroupAddFiles(List[] lists) {
        System.out.println("5 : " + session.isOpen());
        System.out.println("6 : " + session.isOpen());
        Iterator<File> itFile = lists[1].iterator();
        System.out.println("7 : " + session.isOpen());

        org.hibernate.Transaction tx = session.beginTransaction();
        while (itFile.hasNext()) {
            System.out.println("8 : " + session.isOpen());
            Iterator<User> itUser = lists[0].iterator();
            System.out.println("9 : " + session.isOpen());
            File f = itFile.next();
            while (itUser.hasNext()) {
                System.out.println("10 : " + session.isOpen());
                System.out.println("11 : " + session.isOpen());
                User u = itUser.next();
                System.out.println("12 : " + session.isOpen());
                File fCopie = new File(u, f.getName() + "_" + u.getFirstName() + "_" + u.getLastName(), f.getExtension(), f.getSize(), f.getCreatedAt(), f.getUpdateAt());
                System.out.println("13 : " + session.isOpen());
                session.save(fCopie);
                System.out.println("14 : " + session.isOpen());
            }
        }
        tx.commit();
        return lists;
    }

UserDAO.java:

public List[] removeGroupAddUserFiles(List[] lists) {
        System.out.println("15 : " + session.isOpen());
        Iterator<User> itUser = lists[0].iterator();
        System.out.println("16 : " + session.isOpen());

        org.hibernate.Transaction tx = session.beginTransaction();

        while (itUser.hasNext()) {
            System.out.println("17 : " + session.isOpen());
            Iterator<File> itFile = lists[1].iterator();
            System.out.println("18 : " + session.isOpen());
            User u = itUser.next();
            while (itFile.hasNext()) {
                System.out.println("19 : " + session.isOpen());
                File f = itFile.next();
                System.out.println("20 : " + session.isOpen());
                try {
                    u.getFiles().add(f);
                } catch (LazyInitializationException e) {
                    e.printStackTrace();
                }
                System.out.println("21 : " + session.isOpen());
            }
            try {
                session.update(u);
            } catch (ConstraintViolationException e) {
                e.printStackTrace();
            }
            System.out.println("22 : " + session.isOpen());
        }
        tx.commit();
        return lists;
    }

我的代码是多余的,我知道他(它),它正是试图避免会话关闭的问题。

会话结束:

U.getFiles()。add(f);

和HibernateUtil.java:

public class HibernateUtil {

    private static final SessionFactory sessionFactory = buildSessionFactory();

    private static SessionFactory buildSessionFactory() {
        try {
// load from different directory
            SessionFactory sessionFactory = new Configuration().configure("/hibernate.cfg.xml").buildSessionFactory();

            return sessionFactory;

        } catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    public static void shutdown() {
// Close caches and connection pools
        getSessionFactory().close();
    }
}

我在我的代码中放置了session.isOpen()的显示,以及尝试与错误搏斗。程序因此继续,并且系统地向我显示,无论是在例外之前还是之后!

3 个答案:

答案 0 :(得分:12)

一般问题是:你打开事务,用FetchType LAZY创建Hibernate对象。 Hibernate为集合创建代理,它将在首次使用集合时加载对象。您关闭事务,并尝试访问该集合。 Hibernate会话已过期,因为事务已关闭,因此您收到错误。

您应该重新设计代码,以便永远不会从事务块中返回具有单元化代理的对象。您应该从会话中加载集合或evict对象,或者不要自动映射集合(从POJO中删除它们)。

答案 1 :(得分:2)

如果您将hibernate代理实体直接存储在应用程序中,那么它们将在会话生效之前可用。会话关闭后,您无法访问这些实体。如果您在关闭交易后尝试访问它们,您将获得此

org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException  

因此,如果您打算在完成交易后使用它们,那么最好制作一份代理实体的新副本。

答案 2 :(得分:-2)

通过对web.xml进行后续操作,我们可以修复LazyInitilization异常。

<filter>
    <filter-name>OpenSessionInViewFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>OpenSessionInViewFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

访问:http://blog.gmorales.net/2012/03/how-to-solve-orghibernatelazyinitializa.html