如何序列化包含LAZY关联的JSON

15 浏览
0 Comments

如何序列化包含LAZY关联的JSON

我有一个实体类\"Person\",它与\"Contact\"实体类有一个\"ManyToOne\"的关联关系,关联方式为\"LAZY\"。我使用spring-boot暴露REST API。我的POST请求中包含嵌套的JSON,用于保存父实体\"Person\"以及关联的\"Contact\"。\n由于\"Contact\"的关联方式是\"LAZY\",我遇到了以下异常:\n\"ERROR 17415 --- [nio-8080-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.example.rest.RestResultObject[\"results\"]->java.util.ArrayList[0]->com.example.model.Person[\"contact\"]->com.example.model.Contact_$$_jvst8d1_4[\"handler\"])] with root cause\ncom.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.example.rest.RestResultObject[\"results\"]->java.util.ArrayList[0]->com.example.model.Person[\"contact\"]->com.example.model.Contact_$$_jvst8d1_4[\"handler\"])\nat com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77) ~[jackson-databind-2.9.3.jar:2.9.3]\"\n在不将\"Contact\"更改为\"EAGER\"的情况下,有没有更好的解决方法?\n更新内容:\nPerson.java\n

public class Person {
    private long id;
    private String name;
    private String rno;
    @ManyToOne(fetch = FetchType.LAZY)
    private Contact contact;
    // Getters and setters
}

\nContact.java\n

public class Contact {
    private long id;
    private String info;
    @OneToMany
    private List persons;
}

0
0 Comments

一、问题的原因:

问题的出现是因为在序列化一个包含延迟加载(LAZY)关联的JSON时,关联对象(Contact)的属性不会被立即加载,导致在序列化时无法获取到关联对象的数据。

二、解决方法:

为了解决这个问题,可以使用注解@JsonIgnorefetch = FetchType.LAZY

具体的解决方法如下:

1. 在Person类中,将关联对象Contact的加载方式设置为fetch = FetchType.LAZY,即延迟加载。

public class Person {
    private long id;
    private String name;
    private String rno;
    (fetch = FetchType.LAZY)
    private Contact contact;
    // Getters and setters
}

2. 在Contact类中,使用@JsonIgnore注解来忽略关联对象persons的序列化。

public class Contact {
    private long id;
    private String info;
    @JsonIgnore
    private List<Person> persons;
}

通过以上两步的操作,即可解决序列化包含延迟加载关联的JSON时的问题。

这样,当序列化一个包含延迟加载关联的JSON时,关联对象的属性不会被立即加载,从而避免了在序列化时无法获取到关联对象的数据的问题。

0
0 Comments

问题的出现主要与事务处理有关。JSON序列化是在事务范围之外执行的。如果是这样,最简单的解决方案(从架构角度来看并不一定是最好的)是创建一个服务来包装实体加载(专门用于REST操作),并执行相关数据的“去懒加载”操作,例如(关键元素是注释)。

(readOnly=true)
public class DataReaderServiceImpl extends DataLoaderService{
    //初始化代码
    public Person loadPerson(PredicatesType somePredicate){
        Person person = //使用谓词表达式获取人员
        //"去懒加载"事务范围内的联系人
        person.getContacts();
        return person;
    }
}

从架构上讲,在这样的服务中,最好将实体映射到DTO,并返回DTO实例而不是实体。

0
0 Comments

在这个问题中,出现的原因是JSON序列化包含LAZY关联的对象时无法获取关联实体的数据。为了解决这个问题,下面是一些解决方法:

首先,在每个对象上添加以下内容:

- 在id中将long改为Long,这将有助于使用Spring Data JPA。

- 添加@GeneratedValue(strategy = GenerationType.IDENTITY)来声明id为主键。

- 添加@JsonManagedReference和@JsonBackReference来避免Jackson的无限循环。

Person类:

public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String rno;
    @ManyToOne(fetch = FetchType.LAZY)
    @JsonBackReference
    private Contact contact;
    //setter & getter
}

Contact类:

public class Contact {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String info;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "contact")
    @JsonManagedReference
    private List persons;
    //setter & getter
}

然后,添加以下依赖项:


    com.fasterxml.jackson.datatype
    jackson-datatype-hibernate5

最后,添加一个新的配置类:

public class JacksonConfig {
    public Jackson2ObjectMapperBuilderCustomizer addCustomBigDecimalDeserialization() {
        return new Jackson2ObjectMapperBuilderCustomizer() {
            public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {
                jacksonObjectMapperBuilder.featuresToDisable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
                jacksonObjectMapperBuilder.modules(new Hibernate5Module());
            }
        };
    }
}

通过这个解决方案,我们可以获取关联实体的数据。但是有一个问题是,日期的格式不正确。可以通过将日期格式化为所需的格式来解决这个问题。

通过在实体类上添加相应的注解,并添加适当的依赖项和配置,我们可以解决JSON序列化包含LAZY关联的对象的问题。

0