1

I'm having trouble using Hibernate and Jackson together to JSON serialize query results and pass them out to API calls. More specifically, I'm having trouble with a single Entity, EagleUsers. Unless I mark it as @JsonIgnore in the Adjuster Entity, it causes me to get JsonMappingExceptions when serializing. I previously tried this project in C# using the Entity Framework, and I had to exclude EagleUsers entirely to keep the Entity Framework from choking on it.

My suspicion is that it has something to do with Adjuster having two foreign keys to EagleUsers, but I can't seem to figure it out and I've exhausted the ways I can think of to Google the problem.

The backing database is SQL Server 2008.

Here's my relevant code:

Adjuster.java

@Entity
@Table(name = "Adjuster", schema = "dbo", catalog = "censored")
public class Adjuster implements java.io.Serializable {

    private int adjusterId;
    private EagleUsers eagleUsersBySupervisorId;
    private EagleUsers eagleUsersByUserId;

    @Id

    @Column(name = "AdjusterId", unique = true, nullable = false)
    public int getAdjusterId() {
        return this.adjusterId;
    }

    public void setAdjusterId(int adjusterId) {
        this.adjusterId = adjusterId;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "SupervisorId", nullable = false)
    public EagleUsers getEagleUsersBySupervisorId() {
        return this.eagleUsersBySupervisorId;
    }

    public void setEagleUsersBySupervisorId(EagleUsers eagleUsersBySupervisorId) {
        this.eagleUsersBySupervisorId = eagleUsersBySupervisorId;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "UserId", nullable = false)
    public EagleUsers getEagleUsersByUserId() {
        return this.eagleUsersByUserId;
    }

    public void setEagleUsersByUserId(EagleUsers eagleUsersByUserId) {
        this.eagleUsersByUserId = eagleUsersByUserId;
    }
}

EagleUsers.java

@Entity
@Table(name = "EagleUsers", schema = "dbo", catalog = "censored")
public class EagleUsers implements java.io.Serializable {

    private String userId;
    private AspnetUsers aspnetUsers;
    private SubRole subRole;
    private String firstName;
    private String lastName;

    @GenericGenerator(name = "generator", strategy = "foreign", parameters = @Parameter(name = "property", value = "aspnetUsers") )
    @Id
    @GeneratedValue(generator = "generator")

    @Column(name = "UserId", unique = true, nullable = false, length = 36)
    public String getUserId() {
        return this.userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    @OneToOne(fetch = FetchType.LAZY)
    @PrimaryKeyJoinColumn
    public AspnetUsers getAspnetUsers() {
        return this.aspnetUsers;
    }

    public void setAspnetUsers(AspnetUsers aspnetUsers) {
        this.aspnetUsers = aspnetUsers;
    }

    @Column(name = "FirstName", length = 30)
    public String getFirstName() {
        return this.firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    @Column(name = "LastName", length = 45)
    public String getLastName() {
        return this.lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
}

HelloController.java

ObjectMapper mapper = new ObjectMapper();
Hibernate4Module module = new Hibernate4Module();
module.enable(Feature.SERIALIZE_IDENTIFIER_FOR_LAZY_NOT_LOADED_OBJECTS);
module.enable(Feature.FORCE_LAZY_LOADING);
mapper.registerModule(module);
String result = mapper.writeValueAsString(adjusters);
return result;

The exception I'm getting:

2015-10-06 14:26:33.763  INFO 12596 --- [nio-8080-exec-1] o.h.e.internal.DefaultLoadEventListener  : HHH000327: Error performing load command : org.hibernate.type.SerializationException: could not deserialize
2015-10-06 14:26:33.764  INFO 12596 --- [nio-8080-exec-1] o.h.e.internal.DefaultLoadEventListener  : HHH000327: Error performing load command : org.hibernate.type.SerializationException: could not deserialize
2015-10-06 14:26:33.771 ERROR 12596 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception

com.fasterxml.jackson.databind.JsonMappingException: could not deserialize (through reference chain: java.util.ArrayList[0]->radius.hibernate.dao.Adjuster["eagleUsersByUserId"])
    at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:210)
    at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:177)
    at com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:187)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:647)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase._serializeWithObjectId(BeanSerializerBase.java:558)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:145)
    at com.fasterxml.jackson.databind.ser.std.ObjectArraySerializer.serializeContents(ObjectArraySerializer.java:228)
    at com.fasterxml.jackson.databind.ser.std.ObjectArraySerializer.serializeContents(ObjectArraySerializer.java:25)
    at com.fasterxml.jackson.databind.ser.std.ArraySerializerBase.serialize(ArraySerializerBase.java:57)
    at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:100)
    at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:21)
    at com.fasterxml.jackson.databind.ser.std.AsArraySerializerBase.serialize(AsArraySerializerBase.java:183)
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:128)
    at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:2881)
    at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:2338)
    at radius.hibernate.HelloController.index(HelloController.java:157)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:776)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:705)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:858)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1526)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1482)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)
Caused by: org.hibernate.type.SerializationException: could not deserialize
    at org.hibernate.internal.util.SerializationHelper.doDeserialize(SerializationHelper.java:262)
    at org.hibernate.internal.util.SerializationHelper.deserialize(SerializationHelper.java:306)
    at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.fromBytes(SerializableTypeDescriptor.java:155)
    at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.wrap(SerializableTypeDescriptor.java:130)
    at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.wrap(SerializableTypeDescriptor.java:44)
    at org.hibernate.type.descriptor.sql.VarbinaryTypeDescriptor$2.doExtract(VarbinaryTypeDescriptor.java:71)
    at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:64)
    at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:267)
    at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:263)
    at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:253)
    at org.hibernate.type.AbstractStandardBasicType.hydrate(AbstractStandardBasicType.java:338)
    at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2969)
    at org.hibernate.loader.plan.exec.process.internal.EntityReferenceInitializerImpl.loadFromResultSet(EntityReferenceInitializerImpl.java:324)
    at org.hibernate.loader.plan.exec.process.internal.EntityReferenceInitializerImpl.hydrateEntityState(EntityReferenceInitializerImpl.java:251)
    at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.readRow(AbstractRowReader.java:107)
    at org.hibernate.loader.plan.exec.internal.EntityLoadQueryDetails$EntityLoaderRowReader.readRow(EntityLoadQueryDetails.java:255)
    at org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractResults(ResultSetProcessorImpl.java:129)
    at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:138)
    at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:102)
    at org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader.load(AbstractLoadPlanBasedEntityLoader.java:186)
    at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:4126)
    at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:503)
    at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:468)
    at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:213)
    at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:275)
    at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:151)
    at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1070)
    at org.hibernate.internal.SessionImpl.internalLoad(SessionImpl.java:989)
    at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:716)
    at org.hibernate.type.EntityType.resolve(EntityType.java:502)
    at org.hibernate.engine.internal.TwoPhaseLoad.doInitializeEntity(TwoPhaseLoad.java:170)
    at org.hibernate.engine.internal.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:144)
    at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.performTwoPhaseLoad(AbstractRowReader.java:244)
    at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.finishUp(AbstractRowReader.java:215)
    at org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractResults(ResultSetProcessorImpl.java:140)
    at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:138)
    at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:102)
    at org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader.load(AbstractLoadPlanBasedEntityLoader.java:186)
    at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:4126)
    at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:503)
    at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:468)
    at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:213)
    at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:146)
    at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1070)
    at org.hibernate.internal.SessionImpl.immediateLoad(SessionImpl.java:976)
    at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:174)
    at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:286)
    at com.fasterxml.jackson.datatype.hibernate4.HibernateProxySerializer.findProxied(HibernateProxySerializer.java:167)
    at com.fasterxml.jackson.datatype.hibernate4.HibernateProxySerializer.serialize(HibernateProxySerializer.java:85)
    at com.fasterxml.jackson.datatype.hibernate4.HibernateProxySerializer.serialize(HibernateProxySerializer.java:27)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:505)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:639)
    ... 57 common frames omitted
Caused by: java.io.StreamCorruptedException: invalid stream header: 62006100
    at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
    at java.io.ObjectInputStream.<init>(Unknown Source)
    at org.hibernate.internal.util.SerializationHelper$CustomObjectInputStream.<init>(SerializationHelper.java:328)
    at org.hibernate.internal.util.SerializationHelper$CustomObjectInputStream.<init>(SerializationHelper.java:318)
    at org.hibernate.internal.util.SerializationHelper.doDeserialize(SerializationHelper.java:237)
    ... 108 common frames omitted
6
  • Do you use Spring MVC or not ? Commented Oct 6, 2015 at 20:50
  • @André Blaszczyk Yes, this application is using Spring Boot.
    – wMattDodd
    Commented Oct 6, 2015 at 21:36
  • Can you post or link to the mapping exception?
    – Pace
    Commented Oct 6, 2015 at 22:46
  • @Pace I've added the exception log.
    – wMattDodd
    Commented Oct 7, 2015 at 15:09
  • That error looks like it has less to do with serialization to JSON and more to do with deserialization from your database. In particular, it appears that, as part of the serialization, the Hibernate module is trying to load some of your lazy fields from the database. It then looks like it is trying to load a column whose type is VARBINARY and the data in that column is not formatted in the way that Hibernate expected. Is one of the columns in your EagleUsers table a VARBINARY column?
    – Pace
    Commented Oct 7, 2015 at 15:38

2 Answers 2

1

I ran across this: NetBeans Hibernate reverse engineering data types mismatch and it solved my issue. Apparently Hibernate was having trouble with the nvarchar columns in one of the tables related to EagleUsers and Jackson was breaking when it tried to serialize them. Telling Hibernate to map nvarchar to String in hibernate.reveng.xml and then regenerating the mappings fixed it.

0

According to your context, you can try this :

MVC Controller - Spring will handle JSON conversion with @RequestBody

 @Autowired
 AdjustersDAO adjustersDao;

 @Controller
 @RequestMapping("/hello")
 public class HelloController {

     @RequestMapping(value="/adjusters", method=RequestMethod.GET)
     public @ResponseBody List<Adjuster> getAll() {
         return adjustersDao.findAll();
     }
 }

or

RESTful Web Services

 @RestController
 public class HelloController {

     @RequestMapping(value="/adjusters", method = RequestMethod.GET, headers="Accept=application/json")
     public List<Adjuster> getAll() {
         return adjustersDao.findAll();
     }
 }

You also need a JSON library like Jackson :

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>${latest.version}</version>
</dependency>

Not the answer you're looking for? Browse other questions tagged or ask your own question.