5

I have very simple entity object User which has relation to user roles. What is troubling me is when i fetch User object from DB and pass it to another method which wants to access user role inside that user object I'm getting the famous Could not initialize proxy Hibernate Exception.

Ex. method 1:

- open session, open transaction
- fetch user 
- close transaction, close session

Now pass that user object to method 2

- open session, open transaction
- do Hibernate.initialize(user.getUserRole()) --> here it breaks
- close transaction, close session

I'm guessing this is some Hibernate feature where you cannot initialize object in a new session but I have no idea why. Is there any solution to this?

PS. i have read about <property name="hibernate.enable_lazy_load_no_trans">true</property> but this seams like normal thing to do and don't see necessary to turn this option on.

EDIT: code example:

Getters and setter of user class

@ManyToOne(fetch = FetchType.LAZY, targetEntity = UserRoles.class)
@JoinColumn(name = "USER_ROLE_ID", nullable = false)
public UserRoles getUserRoles() {
    return this.userRoles;
}

public void setUserRoles(UserRoles userRoles) {
    this.userRoles = userRoles;
}

Fields of UserRoles

 private Integer id;
 private String description;
 private Character active;
 private Set userses = new HashSet(0);

Method 1

public static void method1() {
    Users user = null;
    Session session = HibernateUtil.getSessionFactory().openSession();
    Transaction tx = null;
    try {
        tx = session.beginTransaction();
        String hqlQuery = "FROM Users WHERE userName = :userName";
        Query query = session.createQuery(hqlQuery);
        query.setParameter("userName", userName);
        List<Users> list = query.list();    
        for (Users u : list) {
            user = u;
            break;
        }
        tx.commit();
    } catch (HibernateException e) {
        if (tx != null)
            tx.rollback();
        Logging.handleExceptionLogging(e);
    } finally {
        session.close();
    }

    method2(user);
}

Method 2

public static method2(Users user) {

if (user != null) {

        if (Hibernate.isInitialized(user.getUserRoles())) {
            if (user.getUserRoles().getDescription() != null && user.getUserRoles().getDescription().toLowerCase().equals("admin"))
                returnValue = true;
        } else {
            Session session = HibernateUtil.getSessionFactory().openSession();
            Transaction tx = null;
            try {
                tx = session.beginTransaction();
                Hibernate.initialize(user.getUserRoles()); // this line causes Exception
                if (user.getUserRoles().getDescription().toLowerCase().equals("admin"))
                    returnValue = true;
                tx.commit();
            } catch (HibernateException e) {
                if (tx != null)
                    tx.rollback();
                Logging.handleExceptionLogging(e);
            } finally {
                session.close();
            }
        }
    }
}
hyperion385
  • 160
  • 3
  • 13

1 Answers1

5

So basically after a lot of google search and reading about sessions my assumption was right. Entity objects are pretty much "bound" to original session where they were fetched and queries like this cannot be performed in this way. One solution is to bound entity to new session calling session.update(entity) and than this new session knows about entity. Basically new query is issued to populate entity fields again. So avoid this if not necessary and try to fetch all needed data in original session.

More read: Could not initialize proxy - no Session

Community
  • 1
  • 1
hyperion385
  • 160
  • 3
  • 13
  • 1
    The session is an implementation of the persistence context. You can think of it as the 1st level cache: the place in memory where Hibernate stores copies of "database objects" (persistent objects read from database, transient objects waiting to be written to database or persistent ones waiting to be updated in the database). When you close the session, you detach your objects from their persistent counterparts. With an update or merge operation you can reattach them. Of course that involves some database operations - if you can do it in one session, you should avoid that overhead. – booFar Apr 28 '23 at 12:28