How to serialize a json containing LAZY associations

Multi tool use
Multi tool use


How to serialize a json containing LAZY associations



I am having an Person entity which has @ManyToOne association with Contact entity with fetch type LAZY. I am using spring-boot to expose REST API. One of my POST call contains nested JSON to save the parent entity Person along with association Contact


Person


@ManyToOne


Contact


Person


Contact



Since Contact fetch type is LAZY, I am encountering into following exception


Contact


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]



Without changing Contact to EAGER. Is there any best way to solve this problem?



Updated:



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;
}





could you please add code for person & contact?
– Maruf Hassan
Jul 1 at 14:55





@MarufHassan Updated my post
– Achaius
Jul 2 at 4:01




2 Answers
2



The problem, most likely, is related to transaction processing. JSON serialization is executed out of transaction scope. If so, the easiest solution (not necessarily the best from the architectural point of view) is to create the service that wrap the entity loading (dedicated for REST operations) and perform "delazyfication" of related data, e.g. (the key element is @Transactional anotation).


@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;
}
}



Architecturally, it would be better, in such a service, to have mapping to DTOs and return DTO instances instead of entities.



I have added the following things



Person class


@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



}



Contact class


@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
}



and add a dependency


<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-hibernate5</artifactId>
</dependency>



and finally add a new config


@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());
}

};
}
}






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

tigccxkMrDWAlvs
si8sCBWTUwit YzIoeaisD1,QtU2

Popular posts from this blog

Rothschild family

Cinema of Italy