来自Java调试器的信息:HTTP状态500 -
类型的异常报告
信息
描述服务器遇到一个内部错误(),阻止它完成这个请求。
例外
javax.servlet.ServletException: java.lang.UnsupportedOperationException:试图序列化 java.lang.Class:org.hibernate.proxy.HibernateProxy。忘记注册类型适配器?
根本原因
java.lang.UnsupportedOperationException:尝试序列化 java.lang.Class:org.hibernate.proxy.HibernateProxy。忘记注册类型适配器?
org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer@7632012e
我正在使用Gson将我的Java对象转换为JSON。以下是我复制粘贴的一些代码。
这是我的资源:
@Stateless
@LocalBean
@Path("/autos")
@Produces(MediaType.APPLICATION_JSON)
public class AutoResource {
@EJB
private CarAssembler warehouse;
@Context
private UriInfo uriInfo;
@GET
public Response allAutos() {
// Building a context, lots of code...
// Creating a Gson instance and configures it...
final Auto auto = warehouse.list(context);
final String autoJson = gson.toJson(auto);
return Response.ok(autoJson).build();
}
}
CarAssembler是一个调用仓库的服务。我没有在这里粘贴服务的代码。
仓库:
@Override
public Question findById(final int id, final FetchType fetchType) {
final Auto question = getEntityManager().find(Auto.class, id);
if (fetchType == FetchType.LAZY) {
return auto;
}
Hibernate.initialize(auto.getManufacturer());
Hibernate.initialize(auto.getAssemblyHouse());
return auto;
}
正如您所看到的,我提供了对象的惰性和及时加载。我使用Hibernate.initialize来急切获取JPA关联。然而,问题是我该如何解决我遇到的代理错误。为什么只有AssemblyHouse仍然附加到JavaAssist,而Manufacturer没有(我已在Java调试器中看到类型)?我如何知道何时取消代理对象?我应该取消此自动化可能具有的所有关联吗?在我的代码的哪个层面?当我取消代理时,它会影响我的应用程序的性能吗?是否有其他解决方案?我从错误消息中看到我可以制作一个类型适配器。是的,我可以这样做,但是我必须为所有域对象执行此操作,以确保转换正确完成。也许当我尝试将其转换为JSON表示形式时,我的域中的其他对象也开始失败,但我不知道何时或为什么。其他对象仅仅是幸运吗?
这是我取消代理对象的方式,但我尚未实现它,因为我不知道这是好还是坏,并且在哪个层面上进行,以及我应该何时执行它。我应该一直取消代理对象吗?
public class HibernateUtilities {
public static <T> T unproxy(T proxy) {
if (proxy == null) {
return null;
}
if (proxy instanceof HibernateProxy) {
Hibernate.initialize(proxy);
HibernateProxy hibernateProxy = (HibernateProxy) proxy;
T unproxiedObject = (T) hibernateProxy.getHibernateLazyInitializer().getImplementation();
return unproxiedObject;
}
return proxy;
}
}
如您所需,以下是堆栈跟踪:
[#|2012-11-22T17:17:13.285+0100|WARNING|glassfish3.1.2|javax.enterprise.system.container.web.com.sun.enterprise.web|_ThreadID=71;_ThreadName=Thread-8;|StandardWrapperValve[javax.ws.rs.core.Application]: PWC1406: Servlet.service() for servlet javax.ws.rs.core.Application threw exception java.lang.UnsupportedOperationException: 尝试序列化java.lang.Class: org.hibernate.proxy.HibernateProxy。忘记注册类型适配器了吗? at com.google.gson.internal.bind.TypeAdapters$1.write(TypeAdapters.java:64) at com.google.gson.internal.bind.TypeAdapters$1.write(TypeAdapters.java:61) at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) at com.google.gson.internal.bind.ArrayTypeAdapter.write(ArrayTypeAdapter.java:93) at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195) at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195) at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195) at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:96) at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:60) at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195) at com.google.gson.Gson.toJson(Gson.java:586) at com.google.gson.Gson.toJson(Gson.java:565) at com.google.gson.Gson.toJson(Gson.java:520) at com.myapp.AutoResource.produceAuto(AutoResource.java:48) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1052) at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1124) at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:5388) at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:619) at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800) at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571) at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doAround(SystemInterceptorProxy.java:162) at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:144) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:861) at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800) at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:370) at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:5360) at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java
final String autoJson = gson.toJson(auto, Auto.class);
进行序列化。如果还是不行,能否把堆栈跟踪信息发出来? - Flavio