Spring代理EntityManager后无法获取具体实现类,求解决方法
你遇到的问题很典型——Spring为了处理事务管理、懒加载以及JPA规范的适配,会给EntityManager生成动态代理类,所以直接调用getClass()或者Spring AOP相关工具类拿到的都是类似com.sun.proxy.$Proxy110的代理对象,根本看不到真实实现。
下面给你几个可行的方法来获取真实的实现类:
方法1:使用unwrap()方法直接获取底层实现
JPA的EntityManager自带了unwrap()方法,可以直接穿透代理拿到底层持久化框架的具体实现类。比如如果你的项目用的是Hibernate,就可以这样写:
// 先unwrap到Hibernate的Session接口 Session hibernateSession = entityManager.unwrap(Session.class); // 再获取真实类名 System.out.println("真实实现类:" + hibernateSession.getClass().getName());
执行后你会看到类似org.hibernate.internal.SessionImpl的结果,这就是Hibernate中EntityManager对应的底层实现类。如果是其他JPA实现(比如EclipseLink),只需要把Session.class换成对应的接口即可(比如EclipseLink的JpaEntityManager.class)。
方法2:从EntityManagerFactory入手
EntityManager是由EntityManagerFactory创建的,你可以先获取工厂类的真实实现,再推断出EntityManager的实现:
EntityManagerFactory emf = entityManager.getEntityManagerFactory(); System.out.println("EntityManagerFactory实现类:" + emf.getClass().getName());
比如Hibernate的工厂类是org.hibernate.jpa.HibernateEntityManagerFactory,对应的EntityManager实现就是org.hibernate.jpa.internal.EntityManagerImpl;EclipseLink的工厂类是org.eclipse.persistence.jpa.JpaEntityManagerFactory,对应的EntityManager实现是org.eclipse.persistence.internal.jpa.EntityManagerImpl。
方法3:IDE调试查看(适合开发阶段)
如果你只是在开发阶段想快速确认,不用写代码,可以在IDE里打个断点,查看entityManager代理对象的内部结构。通常代理对象会有一个target或者delegate属性,里面就藏着真实的实现类实例,直接查看这个属性的类型就行。
为什么之前的方法没用?
你用的AopProxyUtils、AopUtils这些是Spring AOP的工具类,但这里的EntityManager代理并不是Spring AOP生成的——它是JPA规范要求的代理,或者是由持久化框架(比如Hibernate)本身生成的,所以Spring AOP的工具类无法穿透这个代理拿到真实目标。
内容的提问来源于stack exchange,提问作者electrode

