Hibernate, Java : no session or session was closed

22,173

Solution 1

General problem is: you open transaction, create Hibernate object with FetchType LAZY. Hibernate creates proxy for collection, which will load objects on first usage of collections. You close transaction, and try to access that collection. Hibernate session is expired, because transaction is closed, so you got error.

You should redesign your code so to never return object with unitialized proxies out of transaction block. You should either load collections or evict object from session or do not map the collection authomatically (remove them from POJO).

Solution 2

If you store your hibernate proxy entities directly in your application then they will be available until the session is live. once the session is closed, you can not access these entities. if you try to access them after closing transaction, you will get this

org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException  

So it is always better to make a fresh copy of you proxy entities, if you are intented to use them after closing transaction.

Share:
22,173
bbusseuil
Author by

bbusseuil

Updated on August 23, 2020

Comments

  • bbusseuil
    bbusseuil over 3 years

    I already saw this kind of problem on Stackoverflow but nothing could help me to resolve my problem.

    I am novice in Hibernate and have a project to be made in Java and MySQL, and thus use hibernate. I managed to reach my data, to modify them, to deletethem, but I block on a method because I have one exception which arrives.. And seen that I understand still not all the threads I manage not to remove this bug:

    Here is my error :

    org.hibernate.LazyInitializationException Grave: failed to lazily initialize a collection of role: DAO.User.files, no session or session was closed org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: DAO.User.files, no session or session was closed at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358) at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350) at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:343) at org.hibernate.collection.PersistentSet.add(PersistentSet.java:189) at DAO.UserDAO.removeGroupAddUserFiles(UserDAO.java:252) at javaapplication5.JavaApplication5.main(JavaApplication5.java:37)

    And Here are my Java classes :

    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;
        }
    

    My code is redundant, I know him(it), it was exactly to try to avoid the problem of session that closed.

    The session closes in the line:

    U.getFiles () .add (f);

    And 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();
        }
    }
    

    I put a display of session.isOpen() everywhere in my code as well as a try wrestling with the error. The program thus continues, and shows me systematically true, whether it is before or after the exception!

  • bbusseuil
    bbusseuil over 12 years
    I don't really understand what you mean, could you show me an example in my code ? I'm really a noob with Hibernate
  • Danubian Sailor
    Danubian Sailor over 12 years
    org.hibernate.Transaction tx = session.beginTransaction(); tx.commit();