mik*_*ail 5 orm hibernate jpa transactions lazy-loading
有两个JPA实体:具有一对多关系的用户和订单.
/**
* 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;
}
}
Run Code Online (Sandbox Code Playgroud)
我在服务层类中使用这些实体,其中每个方法都在事务中运行.一切都很好,除非服务层类的方法必须返回这些实体.
@Transactional(readOnly=true)
public Set<Order> getOrders() {
Set<Order> orders = user.getOrders();
return orders;
}
Run Code Online (Sandbox Code Playgroud)
This method returns data well. But when I try access to received collection elements I catch exception: "org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: package.User.orders, no session or session was closed".
So, it was excepted. I thought that detaching result will solve my problem, but trick like this
@Transactional(readOnly=true)
public Set<Order> getOrders() {
Set<Order> orders = user.getOrders();
for(Order order: orders)
entityManager.detach(order);
return orders;
}
Run Code Online (Sandbox Code Playgroud)
didn't change anything :(
It doesn't matter for me will info about users attend in set of orders or not. I just want to work with this set and not going to modify it.
Can anybody help me? :)
该方法很好地返回数据.但是,当我尝试访问收到集合元素我赶上例外:"org.hibernate.LazyInitializationException:无法初始化懒洋洋角色的集合:package.User.orders,没有会话或会话已关闭".
错误是自我解释:您正在尝试加载(延迟)加载的集合,但由于User实例已分离,因此不再存在活动会话.
所以,它被排除在外.我认为分离结果将解决我的问题,但这样的伎俩
这不会改变任何事情.该EntityManager#detach(Object)方法不加载任何内容,它从持久化上下文中删除传递的实体,使其分离.
对我来说无关紧要是关于用户是否参加订单的信息.我只是想使用这个集合,而不是去修改它.
您需要使关联EAGER(以便在检索用户时加载Orders)或在检索服务中的用户时使用FETCH JOIN:
SELECT u
FROM User u LEFT JOIN FETCH u.orders
WHERE u.id = :id
Run Code Online (Sandbox Code Playgroud)
我是否正确理解hibernate没有强制加载当前对象的所有延迟关联的标准机制
Hibernate有一个Hibernate.initialize方法,但这显然不是标准的JPA(更喜欢为可移植代码提取连接).
我没办法让hibernate忽略当前对象的懒惰关联(将它们设置为null)
什么?无视你的意思是什么?你为什么要那样做呢?
| 归档时间: |
|
| 查看次数: |
12485 次 |
| 最近记录: |