如果您使用的是Hibernate 5,那么简单地使用EntityManager.unwrap()可能不起作用,这是由于Spring的代理行为和Hibernate中的最新变化(有关详细信息,请参阅this Spring issue,它是固定的,但并不真正)。 为了使它工作,我必须先使用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);
}
6条答案
按热度按时间aoyhnmkz1#
为了全面说明,如果您使用JPA1.0或JPA2.0实现,情况会有所不同。
JPA 1.0版
对于JPA 1.0,您必须使用
EntityManager#getDelegate()
。但请记住,此方法的结果是特定于实现的,即无法从使用Hibernate的应用程序服务器移植到其他应用程序服务器。例如with JBoss,您可以执行以下操作:但是with GlassFish,你得做到:
我同意,这是可怕的,规格是这里的责任(不够清楚)。
JPA 2.0版本
在JPA 2.0中,有一种新的(而且更好的)
EntityManager#unwrap(Class<T>)
方法,对于新的应用程序,它比EntityManager#getDelegate()
更受欢迎。因此,使用Hibernate作为JPA 2.0实现(请参见3.15.原生Hibernate API),您将执行以下操作:
q3qa4bjr2#
请参见《Hibernate ORM用户指南》中的“5.1.从JPA访问Hibernate API”一节:
1dkrff033#
这会解释得更清楚。
ippsafx74#
'entityManager.unwrap(Session.class)'用于从实体管理器获取会话。
演示应用程序link。
46qrfjad5#
如果您使用的是Hibernate 5,那么简单地使用
EntityManager.unwrap()
可能不起作用,这是由于Spring的代理行为和Hibernate中的最新变化(有关详细信息,请参阅this Spring issue,它是固定的,但并不真正)。为了使它工作,我必须先使用
null
进行双重解包:我相信这是由于Spring的
ExtendedEntityManagerCreator
中对代理的unwrap()
方法的处理:irtuqstp6#
我在Wildfly工作但我用的是
正确的答案是