9

我有一个实体,该实体之前已被持久化并@OneToMany与另一个实体有关系。为了添加一个新实体,我只需在托管对象中添加我的新实体并使用它cascadeType.ALL来持久化更改。有没有一种方法可以获取新创建对象的 id 或获取与合并一起使用的原始(非托管)对象以更新其 id?

在伪代码中,我希望会发生以下情况:

  1. 将为合并的实体返回新副本
  2. 旧副本将针对新实体进行更新

示例:父 A,id=13 子 B,id=0

本质上,我想merge在父级persist上发出 a 但在子级上级联(以便更新原始子实例,而不是复制)。

显然这不会发生。我使用休眠作为提供者。

4

4 回答 4

9

只要您进行研究,Stackoverflow帖子JPA 文档就会给出答案。

做我想做的事情的方法是persist托管父母上使用。这将忽略父级上的任何更改,但会级联persist(前提是它设置为级联)。之后子对象将具有正确的 id。

....
JPAEntity newObject=new JPAEntity();
managedObject.addChild(newObject);
em.persist(managedObject)
newObject.getId() //work fine!
于 2013-07-24T10:01:24.700 回答
1

您应该能够“看到”为新实体生成的 ID:

  • 事务提交后,或

  • 在事务处于活动状态时(你的em.flush()在哪里)之后。emEntityManager

另请注意,实体之间的所有关系都需要在持久化之前在 Java 数据结构中解决。孩子对父母的引用需要“设置”,反之亦然。

于 2013-07-23T16:53:46.603 回答
1

确保在保留更改之前设置关系的两个站点。

child.setParent(parent);
parent.getChildren().add(child);
Parent parentWithId = em.merge(parent);
em.flush(); // make sure that the persistence context and database are in sync
parent.getId(); // works
parent.getChildren().get(0).getId(); // should also work
于 2013-07-23T17:13:34.177 回答
1

我对持久性提供程序 eclipselink 也有类似的问题。我需要将具有临时“客户端 orderID”的客户端数据库中的新订单添加到服务器数据库中的现有客户。因为我需要“服务器 orderIDs”来处理进一步的客户端请求,所以我想创建一个映射(clientID、serverID)并将其发送回客户端。基本上我的方法是获取对新添加的子订单副本的引用。它将始终添加到父类客户列表的末尾,该事实用于检索它。

我使用实体类 Customer 和 Order,其中 Customer 有一个订单列表 (LinkedList)。

父客户类:...

    @OneToMany(mappedBy = "customer", cascade=CascadeType.ALL, orphanRemoval = true)
    private List<Order> orders = new LinkedList<Order>();

    public Order getLastOrder() {
      return orders.get(orders.size()-1);
    }

子订单类:

    @ManyToOne(optional=false)
    private Customer customer;

小服务程序:

    Customer customer = customerService.findByID(customerID); //existing customer
    Order order = new Order();
    //add attributes to new order
    customer.addOrder(order);
    customerService.update(customer); //generates keys for children
    order = customer.getLastOrder();
    Long orderID = order.getID; //Nullpointer exception

CustomerService 使用 EntityManager.merge 更新客户,但我忘记更新 servlet 中的引用:

客户服务类:

    public void update(Customer entity) {
      entityManager.merge(entity);
    }  

我这样解决了: CustomerService 类:

    public Customer update(Customer entity) {
      return entityManager.merge(entity);
    }

小服务程序:....

    customer = customerService.update(customer); //generates keys for children

现在一切正常。

于 2014-02-05T13:49:20.870 回答