I have following two domain objects Suggestion and UserProfile
They are mapped with each other in one to many relationship. When I fetch all suggestions using Spring Data JPA, I get corresponding user object with each suggestion objects. This result is observed even when I have set fetch
as FetchType.Lazy
. Following is my code:
Suggestion.java
@Entity
@Table(name="suggestion")
@JsonIgnoreProperties({"suggestionLikes"})
public class Suggestion {
public Suggestion() {
// TODO Auto-generated constructor stub
}
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="suggestion_id")
private Integer suggestionId;
@Column(name="description")
private String description;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="suggestion_by")
private UserProfile user;
//getters and setters
}
UserProfile.java
@Entity
@Table(name = "user_master")
@JsonIgnoreProperties({"suggestions", "suggestionLikes"})
public class UserProfile implements Serializable {
/**
*
*/
private static final long serialVersionUID = 7400472171878370L;
public UserProfile() {
}
@Id
@NotNull
@Column(name = "username", length = 55)
private String userName;
@NotNull
@Column(name = "password")
private String password;
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
private Set<Suggestion> suggestions;
//getters and setters
}
Following is the service which fetches the records:
@Override
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public List<Suggestion> getAllSuggestion() {
return suggestionRespository.findAll();;
}
SuggestionRepository:
@Repository
public interface SuggestionRespository extends JpaRepository<Suggestion,
Integer> {
public List<Suggestion> findAll();
}
Following is the Application class:
@EnableTransactionManagement
@SpringBootApplication
public class AngularSpringbootApplication {
public static void main(String[] args) {
SpringApplication.run(AngularSpringbootApplication.class, args);
}
}
application.properties:
spring.datasource.url=jdbc:mysql://localhost:3306/plan_trip
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.properties.hibernate.dialect =
org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto = update
spring.jackson.serialization.fail-on-empty-beans=false
Response received when getAllSuggestions()
is executed:
[
{
"suggestionId": 2,
"description": "Germanyi!",
"createdBy": "vinit2",
"createdDate": "2018-06-19T10:38:32.000+0000",
"modifiedBy": "vinit2",
"modifiedDate": "2018-06-19T10:38:32.000+0000",
"user": {
"userName": "vinit2",
"password":
"$2a$10$.hP0sQWpl6qqDKiNTkiu0OciQeHRFnkEbEWcDvnv1HY4QCi2tKo.2",
"firstName": "Vinit2",
"lastName": "Divekar2",
"emailAddress": "[email protected]",
"createdBy": null,
"modifedBy": null,
"createdDate": "2018-06-04",
"modifiedDate": "2018-06-04",
"isActive": "1",
"handler": {},
"hibernateLazyInitializer": {}
}
},
{
"suggestionId": 1,
"description": "Vasai!",
"createdBy": "vinit1",
"createdDate": "2018-06-19T10:37:38.000+0000",
"modifiedBy": "vinit1",
"modifiedDate": "2018-06-19T10:37:38.000+0000",
"user": {
"userName": "vinit1",
"password": "$2a$10$D0RMSTWu03Jw7wC1/zqFxOOjb0Do24o/4mq2PhDhRUyBrs8bdGvUG",
"firstName": "Vinit1",
"lastName": "Divekar1",
"emailAddress": "[email protected]",
"createdBy": null,
"modifedBy": null,
"createdDate": "2018-06-04",
"modifiedDate": "2018-06-04",
"isActive": "1",
"handler": {},
"hibernateLazyInitializer": {}
}
}
]
Expected response:
[{
"suggestionId": 2,
"description": "Germanyi!",
"createdBy": "vinit2",
"createdDate": "2018-06-19T10:38:32.000+0000",
"modifiedBy": "vinit2",
"modifiedDate": "2018-06-19T10:38:32.000+0000"
},
{
"suggestionId": 1,
"description": "Vasai!",
"createdBy": "vinit1",
"createdDate": "2018-06-19T10:37:38.000+0000",
"modifiedBy": "vinit1",
"modifiedDate": "2018-06-19T10:37:38.000+0000"
}
]
When I have declared FetchType
as Lazy
, I should not get User objects (in JSON) when I execute findAll()
on Suggestion entity.
What am I missing here?
You can use @JsonManagedReference & @JsonBackReference to prevent proxy call by jakson. Following code may help you.
@JsonBackReference
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
private Set<Suggestion> suggestions;
@JsonManagedReference
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "suggestion_by")
private UserProfile user;
Add the following dependency, change version according to your hibernate
<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());
}
};
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With