How can I get the session object if I have the entity-manager?

是的

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?

145386 次浏览

参见 Hibernate ORM 用户指南中的“ 从 JPA 访问 Hibernate API”部分:

Session session = entityManager.unwrap(Session.class);

为了完全彻底,如果您使用的是 JPA 1.0或 JPA 2.0实现,情况就不同了。

JPA 1.0

对于 JPA 1.0,您必须使用 EntityManager#getDelegate()。但是请记住,该方法的结果是实现特定的即使用 Hibernate 也不能从应用服务器移植到其他服务器。例如 和 JBoss 一起你会做:

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

但是 和 GlassFish 一起,你必须这样做:

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

我同意,这是可怕的,规格是这里的责任(不够清楚)。

JPA 2.0

对于 JPA 2.0,有一种新的(而且更好的) EntityManager#unwrap(Class<T>)方法,对于新的应用程序来说,它比 EntityManager#getDelegate()更受欢迎。

因此,如果使用 Hibernate 作为 JPA 2.0的实现(参见 3.15. 本地 Hibernate API) ,您可以:

Session session = entityManager.unwrap(Session.class);

这样就能解释得更清楚了。

EntityManager em = new JPAUtil().getEntityManager();
Session session = em.unwrap(Session.class);
Criteria c = session.createCriteria(Name.class);

我在 Wildfly 工作,但我在吸毒

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

正确的答案是

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

‘ entityManager.unpack (Session.class)’用于从 EntityManager 获取 session。

@Repository
@Transactional
public class EmployeeRepository {


@PersistenceContext
private EntityManager entityManager;


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


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


}

演示应用程序 link

如果您正在使用 Hibernate 5,那么由于 Spring 的代理行为和 Hibernate 中最近的更改(参见 这期春季特刊,这是固定的,但不是真正的) ,简单地使用 EntityManager.unwrap()可能无法工作。

为了让它工作,我必须先用 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);
}

我相信这是由于在 Spring 的 ExtendedEntityManagerCreator中处理了代理的 unwrap()方法:

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