【问题标题】:Can't Jackson serialize Hibernate Entity杰克逊不能序列化休眠实体
【发布时间】:2015-10-06 20:13:12
【问题描述】:

我无法同时使用 Hibernate 和 Jackson 来 JSON 序列化查询结果并将它们传递给 API 调用。更具体地说,我遇到了单个实体 EagleUsers 的问题。除非我在调整器实体中将其标记为 @JsonIgnore,否则它会导致我在序列化时获取 JsonMappingExceptions。我之前使用实体框架在 C# 中尝试过这个项目,我不得不完全排除 EagleUsers 以防止实体框架窒息。

我怀疑这与 Adjuster 有两个 EagleUsers 的外键有关,但我似乎无法弄清楚,并且我已经用尽我能想到的方法来谷歌这个问题。

后备数据库是 SQL Server 2008。

这是我的相关代码:

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;

我得到的异常:

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

【问题讨论】:

  • 你是否使用Spring MVC?
  • @André Blaszczyk 是的,这个应用程序正在使用 Spring Boot。
  • 您可以发布或链接到映射异常吗?
  • @Pace 我已经添加了异常日志。
  • 该错误看起来与序列化为 JSON 的关系不大,而与数据库的反序列化有关。特别是,作为序列化的一部分,Hibernate 模块似乎正在尝试从数据库中加载一些惰性字段。然后看起来它正在尝试加载类型为 VARBINARY 的列,并且该列中的数据未按照 Hibernate 预期的方式格式化。 EagleUsers 表中的列之一是 VARBINARY 列吗?

标签: java sql-server hibernate jackson


【解决方案1】:

我遇到了这个: NetBeans Hibernate reverse engineering data types mismatch 它解决了我的问题。显然,Hibernate 在与 EagleUsers 相关的一个表中的 nvarchar 列出现问题,而 Jackson 在尝试序列化它们时遇到了问题。告诉 Hibernate 将 nvarchar 映射到 hibernate.reveng.xml 中的 String,然后重新生成映射来修复它。

【讨论】:

    【解决方案2】:

    根据你的情况,你可以试试这个:

    MVC 控制器 - Spring 将使用 @RequestBody 处理 JSON 转换

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

    RESTful Web 服务

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

    你还需要一个像 Jackson 这样的 JSON 库:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-25
      • 2019-04-16
      • 1970-01-01
      • 1970-01-01
      • 2014-09-29
      • 1970-01-01
      • 1970-01-01
      • 2016-01-20
      相关资源
      最近更新 更多