123

I have

private EntityManager em;

public List getAll(DetachedCriteria detachedCriteria)   {

    return detachedCriteria.getExecutableCriteria("....").list();
}

How can I retrieve the session if am using entitymanager, or how can I get the result from my detached criteria?

peterh
  • 11,875
  • 18
  • 85
  • 108
storm_buster
  • 7,362
  • 18
  • 53
  • 75

6 Answers6

203

To be totally exhaustive, things are different if you're using a JPA 1.0 or a JPA 2.0 implementation.

JPA 1.0

With JPA 1.0, you'd have to use EntityManager#getDelegate(). But keep in mind that the result of this method is implementation specific i.e. non portable from application server using Hibernate to the other. For example with JBoss you would do:

org.hibernate.Session session = (Session) manager.getDelegate();

But with GlassFish, you'd have to do:

org.hibernate.Session session = ((org.hibernate.ejb.EntityManagerImpl) em.getDelegate()).getSession(); 

I agree, that's horrible, and the spec is to blame here (not clear enough).

JPA 2.0

With JPA 2.0, there is a new (and much better) EntityManager#unwrap(Class<T>) method that is to be preferred over EntityManager#getDelegate() for new applications.

So with Hibernate as JPA 2.0 implementation (see 3.15. Native Hibernate API), you would do:

import org.hibernate.Session;
...

Session session = entityManager.unwrap(Session.class);
petermeissner
  • 12,234
  • 5
  • 63
  • 63
Pascal Thivent
  • 562,542
  • 136
  • 1,062
  • 1,124
  • 2
    `entityManager.unwrap(Session.class);` what is `Session` in `Session.class`? is it an import? – Thang Pham Jan 13 '11 at 09:19
  • 1
    Depends on JPA implementation, if you're using eclipselink it's `org.eclipse.persistence.sessions.Session` – albciff Nov 29 '19 at 23:13
  • I had to put `@Transactional` on a repository class using `entityManager.unwrap(Session.class)`. Otherwise, I'm getting `java.lang.IllegalStateException: No transactional EntityManager available`. – Dima Korobskiy Dec 23 '20 at 21:48
48

See the section "5.1. Accessing Hibernate APIs from JPA" in the Hibernate ORM User Guide:

import org.hibernate.Session;
...

Session session = entityManager.unwrap(Session.class);
petermeissner
  • 12,234
  • 5
  • 63
  • 63
Vladimir Ivanov
  • 42,730
  • 18
  • 77
  • 103
  • `entityManager.unwrap(Session.class);` what is `Session` in `Session.class`? is it an import? – Thang Pham Jan 13 '11 at 09:21
  • 2
    The Hibernate Manual changed. Point 15.8 no longer gives any information about obtaining a session. – Nicktar Aug 27 '15 at 09:14
  • 3
    As of Jan. 2019, Hibernate current (5.3.7) manual , §5.1, still states this as the way to obtain a reference to a Session object. – Alain BECKER Feb 06 '19 at 23:31
7

This will explain better.

EntityManager em = new JPAUtil().getEntityManager();
Session session = em.unwrap(Session.class);
Criteria c = session.createCriteria(Name.class);
Vadim Martynov
  • 8,602
  • 5
  • 31
  • 43
Enio Dantas
  • 71
  • 1
  • 1
3

'entityManager.unwrap(Session.class)' is used to get session from EntityManager.

@Repository
@Transactional
public class EmployeeRepository {

  @PersistenceContext
  private EntityManager entityManager;

  public Session getSession() {
    Session session = entityManager.unwrap(Session.class);
    return session;
  }

  ......
  ......

}

Demo Application link.

Hari Krishna
  • 3,658
  • 1
  • 36
  • 57
0

If you're using Hibernate 5, simply using EntityManager.unwrap() may not work, due to a combination of Spring's proxy behavior and recent changes in Hibernate (see this Spring issue, which is fixed but not really, for details).

To make it work I had to do a double unwrap first using null:

/**
 * Get the Hibernate {@link Session} behind the given {@link EntityManager}.
 *  
 * @see <a href="https://github.com/spring-projects/spring-framework/issues/19577">Spring Issue #19577</a>
 */         
public static Session getHibernateSession(EntityManager entityManager) {
    Preconditions.checkArgument(entityManager != null, "null entityManager");
    return ((EntityManager)entityManager.unwrap(null)).unwrap(Session.class);
}

I believe this is due to the handling of the proxied unwrap() method in Spring's ExtendedEntityManagerCreator:

...
else if (method.getName().equals("unwrap")) {
    // Handle JPA 2.0 unwrap method - could be a proxy match.
    Class<?> targetClass = (Class<?>) args[0];
    if (targetClass == null) {
        return this.target;
    }
    else if (targetClass.isInstance(proxy)) {
        return proxy;
    }
}
Archie
  • 4,959
  • 1
  • 30
  • 36
-2

I was working in Wildfly but I was using

org.hibernate.Session session = ((org.hibernate.ejb.EntityManagerImpl) em.getDelegate()).getSession();

and the correct was

org.hibernate.Session session = (Session) manager.getDelegate();
brasofilo
  • 25,496
  • 15
  • 91
  • 179