【问题标题】:JPA identifier of an instance of x was alteredx 实例的 JPA 标识符已更改
【发布时间】:2017-10-08 10:29:58
【问题描述】:

大家好,我有一个名为 Product 的课程和一个名为 Supplier 的课程。供应商是产品的父级。

我在带有注释ManyToOne的产品中定义了属性供应商。

创建产品 A 和供应商 S1 后,我先将 S1 与 A 关联。然后,当我尝试将 A 的供应商从 S1 更改为 S2 时,我创建了第二个供应商 S2。 JPA 告诉我“供应商实例的标识符已从 X 更改为 Y”。

我不需要在这里创建/更新供应商。我只想将产品 A 的供应商从一个更改为另一个。

我可以知道哪里出了问题吗?

   @Entity
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id", updatable = false, nullable = false)
    private Long id;
    @ManyToOne(cascade=CascadeType.ALL)
    private Company supplier;
...
}

服务代码:

Product productDB=this.findProductByProductIDCurrentUser(productForm.getId());
    dozer.map(productForm, productDB);
    if(productForm.getSupplier()!=null){
        Company company = 
        companyRepository.findOne(productForm.getSupplier().getId() );
        if(company!=null){
            Company supplier = new Company();
            supplier.setId(productForm.getSupplier().getId());
            productDB.setSupplier(supplier);
        }
    }
    em.merge(productDB);

最好的问候, 约翰

【问题讨论】:

  • 为什么不发布一个代码来显示你在做什么呢?
  • 根据您的要求

标签: java jpa many-to-one dozer


【解决方案1】:

您必须首先在持久性上下文下管理供应商 2。

然后你可以将它设置为Product实体中的引用。

所以..

ProductA productA = session.findProductA(..);

Supplier s2 = new Supplier();
// construct s2

em.merge(s2);

productA.setSupplier(s2);

em.merge(productA); // optional

更新

您也可以尝试分离产品,设置产品并再次合并:

em.detach(product);

product.setSupplier(s2);

em.merge(product);

【讨论】:

  • 感谢您的回复。但就我而言,供应商 1 和 2 都是现有实体。它们不需要创建/更新。我使用 find 方法获取供应商 2 实体并分配给产品 A 实体。但是,JPA 抛出错误。有什么线索吗?
  • 在当前 JPA 实现 AFAIR 中,无法断开一个对象与实体管理器的连接。
  • 对不起应该是分离方法
  • 试过但得到新问题“分离实体传递给坚持:”
猜你喜欢
  • 2015-03-29
  • 1970-01-01
  • 2016-09-28
  • 1970-01-01
  • 1970-01-01
  • 2011-05-09
  • 2012-08-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多