Il y a deux entités JPA : User et Order avec une relation one-to-many.
/**
* User DTO
*/
@Entity
@Table(name="user")
public class User implements Serializable {
private static final long serialVersionUID = 8372128484215085291L;
private Long id;
private Set<Order> orders;
public User() {}
@Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="sequenceUser")
public Long getId() {
return this.id;
}
private void setId(Long id) {
this.id = id;
}
@OneToMany(mappedBy="user", cascade=CascadeType.PERSIST, fetch=FetchType.LAZY)
@LazyCollection(LazyCollectionOption.EXTRA)
public Set<Order> getOrders() {
return orders;
}
public void setOrders(Set<Order> orders) {
this.orders = orders;
}
}
/**
* Order DTO
*/
@Entity
@Table(name="order")
public class Order implements Serializable {
private static final long serialVersionUID = 84504362507297200L;
private Long id;
private User user;
public Order() {
}
@Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="sequenceOrder")
public Long getId() {
return this.id;
}
private void setId(Long id) {
this.id = id;
}
@ManyToOne
@JoinColumn(name="user_id")
public User getUser(){
return user;
}
public void setUser(User user){
this.user = user;
}
}
J'utilise ces entités dans mes classes de la couche service où chaque méthode s'exécute en transaction. Tout va bien, sauf dans les cas où les méthodes des classes de la couche service doivent retourner ces entités.
@Transactional(readOnly=true)
public Set<Order> getOrders() {
Set<Order> orders = user.getOrders();
return orders;
}
Cette méthode renvoie bien les données. Mais lorsque j'essaie d'accéder aux éléments de la collection reçus, j'attrape une exception : "org.hibernate.LazyInitializationException : failed to lazily initialize a collection of role : package.User.orders, no session or session was closed".
Donc, il a été excepté. J'ai pensé que détacher le résultat résoudrait mon problème, mais l'astuce est la suivante
@Transactional(readOnly=true)
public Set<Order> getOrders() {
Set<Order> orders = user.getOrders();
for(Order order: orders)
entityManager.detach(order);
return orders;
}
n'a rien changé :(
Peu m'importe que les informations sur les utilisateurs soient présentes ou non dans le jeu de commandes. Je veux juste travailler avec cet ensemble et ne pas le modifier.
Quelqu'un peut-il m'aider ? :)