I have such kind of @OneToOne Hibernate relationShip
public class Address implements Serializable {
private String id;
private String city;
priv
The easiest solution: Don't serialize entities, use Value Objects.
If that is not an option for you, make sure that the entity Object is detached.
With JPA (2), you would use EntityManager.detach(entity), with plain Hibernate the equivalent is Session.evict(entity).
Within your DAO method add Hibernate.initialize(<your getter method>);
to resolve this.
Student student = findById(<yourId>);
Hibernate.initialize(student.getAddress());
...
return student;
Try like the above.
There is another option that solves your problems. You can add this filter in web.xml
<filter>
<filter-name>springOpenEntityManagerInViewFilter</filter-name>
<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
<init-param>
<param-name>entityManagerFactoryBeanName</param-name>
<param-value>entityManagerFactory</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>springOpenEntityManagerInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
The problem is that entities are loaded lazy and serialization happens before they get loaded fully.
Once I write a processor to handle this but now it's easy to fix this by using the jackson hibernate module.
But how can I serialize to JSON lazy classes using standard jackson message converter which of cause I added to my XML file.
First of all, I don't advise to use DTO/Value Object only to solve this issue.
You may find it easy at the beginning but at each new development/change, the duplicate code means making twice modifications at each time... otherwise bugs.
I don't mean that VO or DTO are bad smells but you should use them for reasons they are designed (such as providing a content/structure that differs according to logical layers or solving an unsolvable serialization problem).
If you have a clean and efficient way to solve the serialization issue without VO/DTO and you don't need them, don't use them.
And about it, there is many ways to solve lazy loading issue as you use Jackson with Hibernate entities.
Actually, the simplest way is using FasterXML/jackson-datatype-hibernate
Project to build Jackson module (jar) to support JSON serialization and deserialization of Hibernate (http://hibernate.org) specific datatypes and properties; especially lazy-loading aspects.
It provides Hibernate3Module/Hibernate4Module/Hibernate5Module
, extension modules that can be registered with ObjectMapper
to provide a well-defined set of extensions related to Hibernate specificities.
To do it working, you just need to add the required dependency and to add the
Jackson Module available during processings where it is required.
If you use Hibernate 3 :
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-hibernate3</artifactId>
<version>${jackson.version.datatype}</version>
</dependency>
If you use Hibernate 4 :
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-hibernate4</artifactId>
<version>${jackson.version.datatype}</version>
</dependency>
And so for...
Where jackson.version.datatype
should be the same for the used Jackson version and the ackson-datatype extension.
If you use or may use Spring Boot, you just need to declare the module as a bean in a specific Configuration
class or in the SpringBootApplication
class and it will be automatically registered for any Jackson ObjectMapper
created.
The 74.3 Customize the Jackson ObjectMapper Spring Boot section states that :
Any beans of type
com.fasterxml.jackson.databind.Module
will be automatically registered with the auto-configuredJackson2ObjectMapperBuilder
and applied to anyObjectMapper
instances that it creates. This provides a global mechanism for contributing custom modules when you add new features to your application.
For example :
@Configuration
public class MyJacksonConfig {
@Bean
public Module hibernate5Module() {
return new Hibernate5Module();
}
}
or :
@SpringBootApplication
public class AppConfig {
public static void main(String[] args) throws IOException {
SpringApplication.run(AppConfig.class, args);
}
@Bean
public Module hibernate5Module() {
return new Hibernate5Module();
}
}