gpt4 book ai didi

java - Jpa 几个 @ManyToOne 与 Cascade

转载 作者:行者123 更新时间:2023-11-30 02:56:01 25 4
gpt4 key购买 nike

我有三个实体: session 、订单和用户(我的在线电影票项目的一部分)。在我的域模型中,订单保留了用户和 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<>();
...
}
<小时/>

我的问题是,我可以在 session 和用户中使用 CascadeType.ALL 吗?使用 session 和用户更新订单时是否存在潜在冲突?

<小时/>

正如你所看到的,我使用了fetchType.Lazy,它能保证Session和User中的订单都是最新的吗?

最佳答案

问题 1:这是一个很好的问题,但为了回答它,您需要了解拥有实体的概念。带有 @ManyToOne 注释的 Entity 是关系的所有者。这对于开发人员来说很重要,因为除非在拥有方完成,否则任何关系都不会持久,在本例中这意味着设置 Order.user。但是,由于您在非拥有的 User 上有 cascade 注释,因此您必须做额外的工作才能使用级联功能:

// 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);

请注意,您必须创建一组订单并设置 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);

现在,只需保存 order 即可通过一次调用保存新的 UserOrder。如果 Order 实体上没有 cascade 注释,则在 User 之前保留 Order 将会出现异常。

引用文献:What is the “owning side” in an ORM mapping? , In a bidirectional JPA OneToMany/ManyToOne association, what is meant by “the inverse side of the association”?

问题2:FetchType.LAZY意味着您必须通过特定查询来获取子项,所以如果我理解您的问题,答案是否定的,它不能保证任何事情。使用FetchType.LAZY,当您获得Session时,当实体分离时,您将无法访问Session.orders,通常是在您离开您的 session Bean 或服务层。如果您需要访问订单,则需要在选择查询中获取它们:

"select distinct s from Session s join fetch s.orders"

编辑:如前所述,默认情况下此查询执行 SQL“内连接”,如果没有订单,则不会返回任何内容。相反,做

"select distinct s from Session s left join fetch s.orders"

以便您始终获得数据库中的 session 。

引用:Difference between FetchType LAZY and EAGER in Java Persistence API?

关于java - Jpa 几个 @ManyToOne 与 Cascade,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37192657/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com