更新嵌套的 OneToMany 休眠实体

Update nested OneToMany hibernate entity

我实现了两个实体。一个 RuleEntity 和一个 RestCallEntity,如下所示:

RuleEntity

    @Entity(name = "RuleEntity")
    @Table(name = "Rule")
    public class RuleEntity {
    
        @Id
        @Column(name = ID_COLUMN_NAME, nullable = false)
        @GeneratedValue(strategy = AUTO)
        private Long id;

        @Column(name = "name", nullable = false)
        public String name = "";
    
        @OneToMany(targetEntity = RestCallEntity.class, fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
        public final Set<RestCallEntity> restCalls = new HashSet<>();
    }

RestCallEntity

@Entity(name = "RestCallEntity")
@Table(name = "RestCall")
public class RestCallEntity

    @Id
    @Column(name = ID_COLUMN_NAME, nullable = false)
    @GeneratedValue(strategy = AUTO)
    private Long id;

    @Column(name = "name", nullable = false)
    public String name = "";
}

我在 json 端点收到一条规则。然后我将收到的 json 规则转换为 RuleEntity 并调用

getEntityManager().merge(ruleEntity);

当我只更改规则名称时,更新工作正常。但是当我更改它的名称时,它看起来像 hibernate 试图创建一个新的 restcall,即使它已经有一个 ID。我得到以下异常。

Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint ?rule_restcall_pkey? Detail: key ?(ruleentity_id, restcalls_id)=(45, 49)? already exists. at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2675) at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2365) at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:355) at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:490) at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:408) at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:166) at org.postgresql.jdbc.PgPreparedStatement.executeUpdate(PgPreparedStatement.java:134) at io.agroal.pool.wrapper.PreparedStatementWrapper.executeUpdate(PreparedStatementWrapper.java:88) at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:197) ... 99 more

所以我终于想通了,可能是equals/hashcode方法的实现导致的。我将 equals 方法更改为仅检查 id,将 hashcode 方法更改为仅 return id 的哈希码。现在更新工作正常。