4

Im trying to convert a collection (obtained from Hibernate) to json string using Gson for use in my restful service. But, the service is giving me http 500 error.

My code is as under:

@GET
@Path("/getScheduleLookUp")
@Produces(MediaType.APPLICATION_JSON)
public String getScheduleLookUp() throws IOException {
    ScheduleLookupDAO lookupDAO = new ScheduleLookupDAO();
    return new Gson().toJson(lookupDAO.getAllScheduleLookUps());
}

The hibernate list which is returned after querying the DB returns classname with some garbage value attached to it, may be because of lazy loading by Hibernate.I tried by turning lazy loading off also, but ended up with the same result. My class structure is somewhat like this

public class ScheduleLookup extends BaseModel {

private static final long serialVersionUID = -2561410864465885712L;

private Integer scheduleId;
private String scheduleName;
private ClientLookup clientLookup;
private String description;
private Route route;
private String routeName;
private Double estimatedDuration;
private Double calculatedDuration;
private UserLookup createdBy;
private Date createdAt;
private UserLookup lastUpdatedBy;
private Date lastUpdatedAt;
private Boolean delFlag;
private UserLookup deletedBy;
private Date deletedAt;
private Boolean isSkipped;
private Integer daySpan;

Now when i debugged it , i found that the returned list had references of ClientLookup as ClientLookup$$Enhance... because of which is causing the problem.I tried to remove the proxies also but didn help. This is what I had tried to remove the proxy (found at one SO results)

public static <T> T initializeAndUnproxy(T entity) {
    if (entity == null) {
        throw new 
           NullPointerException("Entity passed for initialization is null");
    }

    Hibernate.initialize(entity);
    if (entity instanceof HibernateProxy) {
        entity = (T) ((HibernateProxy) entity).getHibernateLazyInitializer()
                .getImplementation();
    }

    return entity;
}

Error trace is as under :

java.lang.UnsupportedOperationException: Attempted to serialize java.lang.Class: org.hibernate.proxy.HibernateProxy. Forgot to register a type adapter?
at com.google.gson.internal.bind.TypeAdapters$1.write(TypeAdapters.java:67)
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.ObjectTypeAdapter.write(ObjectTypeAdapter.java:107)
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.Gson.toJson(Gson.java:593)
at com.google.gson.Gson.toJson(Gson.java:572)
at com.google.gson.Gson.toJson(Gson.java:527)
at com.google.gson.Gson.toJson(Gson.java:507)
at com.pcs.bpems.services.SchedulesService.getScheduleLookUp(SchedulesService.java:32)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60)
at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$TypeOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:185)
at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:302)
at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108)
at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1480)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1411)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1360)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1350)
at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:538)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:716)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)

I had also added lazy="no-proxy" in hbm file but to no avail

<class name="com.test.ScheduleLookup" table="schedule_lookup">
    <id name="scheduleId" type="java.lang.Integer">
        <column name="schedule_id" />
        <generator class="native" />
    </id>
    <many-to-one name="clientLookup"
        class="com.test.hibernate.models.ClientLookup" fetch="select" lazy="no-proxy">
        <column name="client_id" />
    </many-to-one>.....

Any help would be greatly appreciated!

Anish
  • 255
  • 2
  • 4
  • 15
  • Can you please share error traces. – Dark Knight Nov 05 '13 at 05:56
  • Code for `ScheduleLookupDAO` might help in getting an answer –  Nov 05 '13 at 05:59
  • I have added the stack trace for your reference – Anish Nov 05 '13 at 06:06
  • Can u check http://stackoverflow.com/questions/11518091/how-to-properly-convert-list-of-specific-objects-to-gson and http://stackoverflow.com/questions/16576009/java-lang-unsupportedoperationexception-attempted-to-serialize-java-lang-class – Karthik Nov 05 '13 at 07:05
  • @Karthik : I have checked both.As far as unproxying is considered, it doesnt seem to work as Hibernate declares it to be an instance not of proxy.Regarding the Adapter,for Gson, we can only put values as String and not as objects.I guess there should be something which will ensure when we retrieve data back frm Hibernate, types come as full qualified classnames instead of ' Classname$$$ ' as in my case.had tried lazy="no-proxy" also but to no avail(please see the updated code). – Anish Nov 05 '13 at 08:08
  • I finally achieved it by eager loading but that seems to have a performance since my db is huge.Hence,I have explicitly written custom SQL's to achieve the same :) – Anish Nov 09 '13 at 07:59

3 Answers3

8

A great answer to this question was provided here - Could not serialize object cause of HibernateProxy

The recommended way is to use a TypeAdapter without manually unproxying every object. Then you would register the TypeAdapter with Gson.

Community
  • 1
  • 1
Jeremy
  • 2,970
  • 1
  • 26
  • 50
0

Try parsing through ObjectMapper as

ScheduleLookupDAO lookupDAO = new ScheduleLookupDAO();
return new ObjectMapper().writeValueAsString(lookupDAO.getAllScheduleLookUps());
-1

Create a new Object that has only attributes you want to convert to JSON. Then Map the hibernate object ( getAll() ) and map each object to ur new Object type. Return a List of those converted objects.