我有一个Person
实体,该实体与@ManyToOne
实体具有Contact
关联,且实体类型为LAZY。我正在使用spring-boot公开REST API。我的POST调用之一包含嵌套的JSON以保存父实体Person
以及关联Contact
由于Contact
的提取类型为LAZY,因此我遇到以下异常
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
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"])
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77) ~[jackson-databind-2.9.3.jar:2.9.3]
不将Contact更改为EAGER。有什么最佳方法可以解决此问题?
已更新:
Person.java
public class Person {
private long id;
private String name;
private String rno;
@ManyToOne(fetch = FetchType.LAZY)
private Contact contact;
// Getters and setters
}
Contact.java
public class Contact {
private long id;
private String info;
@OneToMany
private List<Person> persons;
}
答案 0 :(得分:2)
我添加了以下内容
人员班
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String rno;
@JsonManagedReference
@ManyToOne(fetch = FetchType.LAZY)
private Contact contact;
//setter & getter
}
联系方式
@Entity
public class Contact {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String info;
@JsonBackReference
@OneToMany(cascade = CascadeType.ALL, mappedBy = "contact")
private List<Person> persons;
//setter & getter
}
并添加依赖项
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-hibernate5</artifactId>
</dependency>
最后添加一个新配置
@Configuration
public class JacksonConfig {
@Bean
public Jackson2ObjectMapperBuilderCustomizer addCustomBigDecimalDeserialization() {
return new Jackson2ObjectMapperBuilderCustomizer() {
@Override
public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {
jacksonObjectMapperBuilder.featuresToDisable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
jacksonObjectMapperBuilder.modules(new Hibernate5Module());
}
};
}
}
答案 1 :(得分:0)
问题很可能与交易处理有关。 JSON序列化是在事务范围之外执行的。如果是这样,最简单的解决方案(从体系结构的角度来看不一定是最好的)是创建包装实体加载(专用于REST操作)并执行相关数据“脱氨化”的服务。 (关键元素是@Transactional
注释)。
@Sevice
@Transactional(readOnly=true)
public class DataReaderServiceImpl extends DataLoaderService{
//initialization code
public Person loadPerson(PredicatesType somePredicate){
Person person = //get person using predicates expression
//"delazy" contacts in transaction scope
person.getContacts();
return person;
}
}
在架构上,在这种服务中,最好映射到DTO并返回DTO实例而不是实体。