hyperion385
hyperion385

Reputation: 168

Hibernate initialize object in another session

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

Upvotes: 5

Views: 3455

Answers (1)

hyperion385
hyperion385

Reputation: 168

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

Upvotes: 5

Related Questions