Hibernate中javassist_16无法转换为Proxy的类型转换异常求助
{ClassName}_$$_javassist_16 cannot be cast to javassist.util.proxy.Proxy异常 这个问题我之前帮同事排查过类似的,结合你的环境(Java 8、Spring MVC 4.0.6、Hibernate 4.3.6、Tomcat 8.5),核心原因基本都是类加载器冲突或者Javassist版本不兼容,给你几个可行的解决步骤:
1. 统一Javassist版本,排除冲突依赖
Hibernate 4.3.6.Final本身依赖的是javassist:3.18.1-GA,如果你手动添加了其他版本的Javassist,会导致同一个类被不同类加载器加载,从而触发类型转换异常。
在Gradle里可以通过以下配置强制统一版本:
// 排除所有依赖中自带的javassist configurations.all { exclude group: 'org.javassist', module: 'javassist' } dependencies { // 明确指定和Hibernate 4.3.6兼容的javassist版本 implementation 'org.javassist:javassist:3.18.1-GA' // 你的其他依赖 implementation 'org.hibernate:hibernate-core:4.3.6.Final' implementation 'org.springframework:spring-webmvc:4.0.6.RELEASE' // ...其他依赖 }
2. 检查Tomcat容器级的Javassist冲突
Tomcat的类加载机制是优先加载容器lib目录下的jar包,如果你的Tomcat的CATALINA_HOME/lib或CATALINA_BASE/lib目录里存在javassist的jar包,会和你应用WEB-INF/lib里的版本冲突。
解决方法:
- 找到Tomcat lib目录下的
javassist-*.jar,删除它,让应用使用自己打包的版本。
3. 避免实体类被多重代理
如果你的实体类同时被Hibernate懒加载代理和Spring AOP代理(比如事务、日志切面),两种代理叠加会导致类型转换失败。
可以尝试:
- 对需要懒加载的实体类,避免添加Spring AOP切面;
- 如果必须使用AOP,将Spring AOP的代理方式改为基于接口的代理(前提是实体类实现了对应的接口)。
4. 验证依赖树,确认无版本冲突
用Gradle命令查看完整依赖树,确认没有多个Javassist版本存在:
./gradlew dependencies
在输出中搜索javassist,确保只有3.18.1-GA这一个版本被引入。
你遇到的异常信息:
Exception : java.lang.ClassCastException: {ClassName}_$$_javassist_16 cannot be cast to javassist.util.proxy.Proxy
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.getProxy(JavassistLazyInitializer.java:147) ~[hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.proxy.pojo.javassist.JavassistProxyFactory.getProxy(JavassistProxyFactory.java:75) ~[hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.tuple.entity.AbstractEntityTuplizer.createProxy(AbstractEntityTuplizer.java:771) ~[hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.createProxy(AbstractEntityPersister.java:4613) ~[hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.event.internal.DefaultLoadEventListener.createProxyIfNecessary(DefaultLoadEventListener.java:350) ~[hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:271) ~[hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:151) ~[hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1070) ~[hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.internal.SessionImpl.internalLoad(SessionImpl.java:989) ~[hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:716) ~[hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.type.EntityType.resolve(EntityType.java:502) ~[hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at org.hibernate.engine.internal.TwoPhaseLoad.doInitializeEntity(TwoPhaseLoad.java:170) ~[hibernate-core-4.3.6.Final.jar:4.3.6.Final]
内容的提问来源于stack exchange,提问作者venkat

