【问题标题】:Jackson JPA persisting foreign key composite-id fails杰克逊 JPA 持久化外键复合 ID 失败
【发布时间】:2026-02-23 11:25:01
【问题描述】:

我有一个 JPA 实体,其外键是复合 ID 的一部分:

@Entity
@IdClass(CustomerId.class)
public class Customer {

    @Id
    public String id;

    @Id
    @ManyToOne
    public Company company;

}

public class CustomerId  {

    public String id;

    public String company;

}

@Entity
public class Company {

    @Id
    public String id;

    public String name;

}

它有效。问题是当我收到一个要持久化的 JSON 对象并且 Jackson 将其反序列化为 POJO 时:

{
    "id": "Cust0001",
    "company": {
        "id": "Comp1"
     }
}

这是 JAX-RS 资源:

@Path("/customers")
public class CustomerResource {

    @PersistenceContext
    EntityManager em;

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    public void post(Customer customer) {
        em.persist(customer);
    }

}

这失败了,因为 JPA(我使用 Hibernate)尝试将 persist 级联到具有 id“Comp1”的 Company 的非托管实例,从而引发 EntityExistsException

我发现完成这项工作的唯一方法是:

customer.company = em.merge(customer.company);
em.persist(customer);

但我正在寻找一个通用的解决方案,因为我有几十个像 Customer 这样的实体,并且他们的 JAX-RS 资源扩展了一个抽象资源,我不知道在持久化实体之前要合并/设置什么。

更新

尝试将两个未序列化的对象与对同一实体的引用合并时出现同样的问题,例如

{
    "id": "Cust0001",
    "company": {
        "id": "Comp1"
     },
     relatedCustomer: {
        "id": "Cust9999",
        "company": {
           "id": "Comp1"
        }
     }
}

合并它也会抛出一个关于Company#Comp1EntityExistsException

【问题讨论】:

    标签: java json hibernate jpa jackson


    【解决方案1】:

    在实体类上使用 @JsonIdentityInfo 解决,这使得 Jackson 使用与每个实体的同一实例相关联的标识符对对象进行无冗余的反序列化/序列化。

    【讨论】:

      【解决方案2】:

      Hibernate 不支持复杂查询.. 请阅读 hibernate 文档。 请选择 hql

      【讨论】: