ivy*_*ivy 3 java spring hibernate jpa cascade
我有三个实体,Session、Order 和 User(我的在线电影票项目的一部分)。在我的域模型中,Order 保留了 User 和 Session 的 fk。正如你在我的代码中看到的:
@Table(name="Orders")
@Entity
public class Order {
@ManyToOne
@JoinColumn(nullable = false)
private User user;
@ManyToOne
private Session session;
...
}
@Entity
@Table(name="Session")
public class Session {
@OneToMany(fetch=FetchType.LAZY,
cascade = CascadeType.ALL,
mappedBy = "session")
private List<Order> orders = new ArrayList<Order>();
...
}
@Table(name="User")
@Entity
public class User {
@OneToMany(cascade = { CascadeType.PERSIST,
CascadeType.MERGE,
CascadeType.REMOVE },
mappedBy = "user")
private @Getter Set<Order> orders = new HashSet<>();
...
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,我可以CascadeType.ALL在 Session 和 User 中使用吗?使用 Session 和 User 更新 Order 时是否存在潜在冲突?
可以看到,我用的是fetchType.Lazy,能保证Session和User中的订单都是最新的吗?
问题 1:这是个好问题,但要回答它,您需要了解owning实体的概念。在Entity与@ManyToOne注释的关系的所有者。这对开发人员很重要,因为除非在拥有方完成,否则不会持久化任何关系,在这种情况下,这意味着设置Order.user. 但是,由于您cascade在 non-owning 上有注释User,您必须做额外的工作才能使用级联功能:
// create Order
Order order = new Order();
// create User and Set of orders
User user = new User();
Set<Order> userOrders = new HashSet<Order>();
user.setOrders(userOrders);
userOrders.add(order);
// and set Order.user
order.setUser(user);
// persist with cascade
em.persist(user);
Run Code Online (Sandbox Code Playgroud)
请注意,您必须创建一组订单并设置 Order.user 以保持级联。但是,如果您将cascade注释放在拥有实体上Order,那么您的工作就会变得简单得多:
// create User
User user = new User();
// create Order
Order order = new Order();
// and set Order.user
order.setUser(user);
// persist with cascade
em.persist(order);
Run Code Online (Sandbox Code Playgroud)
现在只要坚持order就会坚持新的User和Order一个电话。如果没有实体cascade上的注释Order,坚持Order之前User会给你一个例外。
参考资料:ORM 映射中的“拥有方”是什么?,在双向 JPA OneToMany/ManyToOne 关联中,“关联的反面”是什么意思?
问题2:FetchType.LAZY意味着您必须通过特定查询来获取孩子,所以如果我理解您的问题,答案是否定的,它不能保证任何事情。随着FetchType.LAZY当你得到一个Session你不会有机会获得Session.orders当实体变得独立,你已经离开了您的会话Bean或服务层通常之后。如果您需要访问订单,则需要在选择查询中获取它们:
“从 Session s join fetch s.orders 中选择不同的 s”
编辑:如前所述,默认情况下,此查询执行 sql“内部联接”,如果没有订单,它将不返回任何内容。相反,做
“从 Session s left join fetch s.orders 中选择不同的 s”
以便您始终获得数据库中的会话。
参考:Java Persistence API 中 FetchType LAZY 和 EAGER 的区别?
| 归档时间: |
|
| 查看次数: |
5838 次 |
| 最近记录: |