Reputation: 21
I am using JPA with hibernate in my spring boot application. Whenever I try to fetch the enities using jpa methods, its returning the entity plus all the association present inside it. I wanted to fetch the associated entities on demand(lazy loading), so I have provided fetch=FetchType.LAZY in my domain class. But still its returning all the entries.
Below is the code: Case.java
@Entity
@Table(name="smss_case")
public class Case implements Serializable {
/**
*
*/
private static final long serialVersionUID = -2608745044895898119L;
@Id
@Column(name = "case_id", nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer caseId;
@Column( name="case_title" )
private String caseTitle;
@JsonManagedReference
@OneToMany(mappedBy="smmsCase", cascade = CascadeType.ALL, fetch=FetchType.LAZY)
private Set<Task> tasks;
}
}
Task.java
@Entity
@Table(name="task_prop")
public class Task implements Serializable {
/**
*
*/
private static final long serialVersionUID = -483515808714392369L;
@Id
@Column(name = "task_id", nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer taskId;
@Column(name="task_title")
private String taskTitle;
@JsonBackReference
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn( name="case_id", nullable=false)
private Case smmsCase;
// getters and setters
}
Service.java
public Case getCases(Integer id) {
return dao.findById(1).get();
}
Dao.java
public interface ServiceDao extends JpaRepository<Case, Integer>{
}
{
"caseId":1,
"caseTitle":"ergonomics",
"tasks":[
{
"taskId":1,
"taskTitle":"ca"
},
{
"taskId":2,
"taskTitle":"hazards"
},
{
"taskId":3,
"taskTitle":"remedy"
}
]
}
Any help will be highly appreciated!
Thanks!
Upvotes: 2
Views: 5617
Reputation: 16628
Was tricky to investigate but I had this issue as I was using mapstruct and it happens to do deep/ nested mapping and in the process, it calls getter of the lazy loaded property. The issue was resolved when I used mapstrct @BeforeMapping
.
@Mapper
public interface HibernateAwareMapper {
@BeforeMapping
default <T> Set<T> fixLazyLoadingSet(Collection<?> c, @TargetType Class<?> targetType) {
if (!Util.wasInitialized(c)) {
return Collections.emptySet();
}
return null;
}
@BeforeMapping
default <T> List<T> fixLazyLoadingList(Collection<?> c, @TargetType Class<?> targetType) {
if (!Util.wasInitialized(c)) {
return Collections.emptyList();
}
return null;
}
class Util {
static boolean wasInitialized(Object c) {
if (!(c instanceof PersistentCollection)) {
return true;
}
PersistentCollection pc = (PersistentCollection) c;
return pc.wasInitialized();
}
}
}
Upvotes: 2