Java 休眠插入到OneToMany
我刚刚开始使用Hibernate,我想知道如何在不首先加载容器的情况下将新元素插入到oneToMany关系中 考虑以下示例:Java 休眠插入到OneToMany,java,hibernate,one-to-many,Java,Hibernate,One To Many,我刚刚开始使用Hibernate,我想知道如何在不首先加载容器的情况下将新元素插入到oneToMany关系中 考虑以下示例: @Entity @Table(name="orders") class Order { @Id @GeneratedId public Long id; @OneToMany(mappedBy="order") public List<Item> items = new ArrayList<Item>(); } @
@Entity
@Table(name="orders")
class Order {
@Id @GeneratedId
public Long id;
@OneToMany(mappedBy="order")
public List<Item> items = new ArrayList<Item>();
}
@Entity
@Table(name="items")
class Item {
@Id @GeneratedId
public Long id;
@ManyToOne
public Order order;
}
@实体
@表(name=“orders”)
阶级秩序{
@Id@GeneratedId
公共长id;
@OneToMany(mappedBy=“订单”)
public List items=new ArrayList();
}
@实体
@表(name=“items”)
类项目{
@Id@GeneratedId
公共长id;
@许多酮
公共秩序;
}
我想在订单中插入一个新项目(我知道订单的id并且它是有效的),但我不想先加载订单。显然,这应该是可能的,因为SQL只需要插入的id,而不需要整个Order对象。我不认为您可以,Hibernate需要在会话/上下文中拥有订单,然后才能向其添加项目。i、 e.Hibernate需要“知道”项目顺序。我认为您不能,Hibernate需要在会话/上下文中获得顺序,然后才能向其中添加项目。i、 e.Hibernate需要“知道”项目的顺序。你可以通过创建一个新的
项目来做到这一点,而不需要订单
,保存它,然后使用本机查询从新的项目
中更新订单id
值。你可以通过创建一个新的项目
而不需要订单
,保存它,然后使用本机查询从新的项
更新订单id
值。您应该能够轻松地在Hibernate中完成这一切
Item item - new Item();
Order order = new Order();
order.setId(order_id);
item.setOrder(order);
em.persist(item);
确保在项目实体的order属性上正确设置了cascade属性。如果不这样做,最终可能会无意中更改值的顺序
@ManyToOne(cascade=CascadeType.PERSIST)
应该没问题。仅当订单不存在时,才允许从项目侧更改订单
另一方面,您可能希望将这种关系看作是一种多个关系,因为在多个订单上订购商品是有意义的。您应该能够轻松地在Hibernate中完成这一切
Item item - new Item();
Order order = new Order();
order.setId(order_id);
item.setOrder(order);
em.persist(item);
确保在项目实体的order属性上正确设置了cascade属性。如果不这样做,最终可能会无意中更改值的顺序
@ManyToOne(cascade=CascadeType.PERSIST)
应该没问题。仅当订单不存在时,才允许从项目侧更改订单
另一方面,您可能希望将这种关系看作是一种多个关系,因为在多个订单上有项目是有意义的。“幸运的是”您没有任何级联策略,并且依赖关系设置在项目端
您可以使用session.load()加载具有所需ID的用户。如果在会话中找不到代理,load()方法将返回代理。当您想要设置依赖项而不去db获取实体时,这非常有用
它看起来像:
Order order = session.load(Order.class, orderId); // no DB call
Item item = new Item();
item.setOrder(order);
// set other attributes of item
session.save(item);
有关load()和get()的区别,请参阅
“幸运的是”您没有任何级联策略,依赖项设置在项目端
您可以使用session.load()加载具有所需ID的用户。如果在会话中找不到代理,load()方法将返回代理。当您想要设置依赖项而不去db获取实体时,这非常有用
它看起来像:
Order order = session.load(Order.class, orderId); // no DB call
Item item = new Item();
item.setOrder(order);
// set other attributes of item
session.save(item);
有关load()和get()的区别,请参阅
啊,说得好。只要order_id不是强制性的,那么查询就可以了。啊,这一点很好。只要订单id不是强制性的,那么查询就可以工作。不是真的,请参考我的答案不是真的,请参考我的答案如果我理解正确,这种方法实际上不是你应该做的事情。在Hibernate中,我们只希望会话中只存在一个具有相同标识符的实体实例。虽然您正在欺骗Hibernate,并且这次它可以工作,但它不能保证在其他版本中工作,因为它违背了Hibernate的设计。谁知道Hibernate什么时候会在类似的场景中添加额外的实体有效性检查呢?如果我理解正确的话,这个方法实际上不是您应该做的事情。在Hibernate中,我们只希望会话中只存在一个具有相同标识符的实体实例。虽然您正在欺骗Hibernate,并且这次它可以工作,但它不能保证在其他版本中工作,因为它违背了Hibernate的设计。谁知道在类似的场景中,Hibernate何时会添加对实体有效性的额外检查?