【问题标题】:JPA Exception saving parent/childrenJPA Exception 保存父/子
【发布时间】:2019-05-08 22:59:22
【问题描述】:

我正在使用 JPA 并且有以下内容:

ProductEntity 

@Basic
@Column(name = "PRODUCT_ID", nullable = false, length = 128)
private String productId;

@ManyToOne
@JoinColumn(name = "PARENT_ID")
private ProductEntity parent;

如您所见,产品表可以有父表。实际上是父子关系。

我在数据库中保存了一个产品,然后我添加了一些子产品,每个子产品都有相同的父产品。

  • 父产品有ProductEntity parent = null;
  • 子产品有 ProductEntity parent = 父产品;

    ProductEntity parentProductEntity = ...
    ProductEntity childProductEntity1 = ...
    ProductEntity childProductEntity2 = ...
    
    em.persist(parentProductEntity);
    childProductEntity1.setParent(parentProductEntity);
    childProductEntity2.setParent(parentProductEntity);
    em.merge(childProductEntity1);
    

数据(它从不插入最后两个子行)

    ID        PRODUCT_ID     PARENT_ID
     1           1              null
     2           2                1
     3           3                1

问题

然后我尝试保存每个子产品。但是我收到一个错误,表明存在重复的密钥(productId)。保存孩子时,它也在尝试保存父项的重复条目。

原因:org.postgresql.util.PSQLException: ERROR: duplicate key 值违反了唯一约束“t_osm_product_product_id_uindex”

问题

我必须如何更改我正在执行的操作才能成功保存每个子产品?

谢谢

【问题讨论】:

  • 如果你设置了子产品的父级,你能显示你的代码吗?
  • @RezaNasiri 谢谢,我已经更新了上面的解释。
  • 好像没问题,你用什么策略生成主键?
  • 该表有一个PK ID(自增)和一个唯一约束PRODUCT_ID(由代码生成,但始终唯一)。
  • 你需要用“@Id”而不是“@Basic”来注释你的PK

标签: java database jpa


【解决方案1】:

你的实体应该是这样的

@Id
Long ID;

@Column(name = "PRODUCT_ID", nullable = false, length = 128)
private String productId;

@ManyToOne
@JoinColumn(name = "PARENT_ID")
private ProductEntity parent;

您的代码中的其他一切似乎都很好。

数据库中的数据将如下所示

 ID        PRODUCT_ID     PARENT_ID
 1           abc              null
 2           def                1
 3           xyz                1

【讨论】:

    【解决方案2】:

    请更改以下几点并检查:-

    • 使用“persist”而不是“merge”并按照以下顺序执行操作。

    {

    public static void main (String[] agrs){
    EntityManager em = ... // from EntityManagerFactory, injection, etc.
    
    em.getTransaction().begin();
    
    A parent   = new A();
    A son      = new A();
    A daughter = new A();
    
    son.setParent(parent);
    daughter.setParent(parent);
    
    em.persist(parent);
    em.persist(son);
    em.persist(daughter);
    
    em.getTransaction().commit();
    }
    

    【讨论】:

    • 谢谢@Parkash。我尝试更改它,使其仅执行“持久”而不是“合并”,但现在我得到以下信息: java.lang.IllegalStateException:在同步期间,通过未标记为级联 PERSIST 的关系找到了一个新对象:产品实体(productId=c0f3fd35-ed7e-48d1-8b3e-14cbb5a3a502)。
    • 请用@ManyToOne注解设置“cascade=CascadeType.ALL”并检查。
    【解决方案3】:

    你可以试试@ManyToOne(cascade=CascadeType.MERGE)

    【讨论】:

    • 不,不幸的是,我仍然遇到同样的问题
    猜你喜欢
    • 2022-01-20
    • 2018-11-06
    • 2021-05-31
    • 2017-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-05
    • 2019-12-05
    相关资源
    最近更新 更多