【问题标题】:How to persist an entity with multiple fields of a single type using JPA?如何使用 JPA 持久化具有单一类型的多个字段的实体?
【发布时间】:2018-06-07 09:58:34
【问题描述】:

背景:

我有一个抽象类MobileResource,它包含三个字段,每个字段类型为Site。这些字段可以并且通常确实包含相同的对象。

@Entity
public abstract class MobileResource extends Resource implements Serializable {

    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
    private Site homeSite;
    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
    private Site currentSite;
    @ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST})
    private Site relocationSite;

    // constructors, getters, setters
}

我还有一个 Person 的具体子类 MobileResource

@Entity
public class Person extends MobileResource implements Serializable {

    private String firstName;
    private String surname;

    // constructors, getters, setters
}

有问题的模块是一个 spring-boot 应用程序,它使用 spring-data-jpa 一个 postgres 数据库。数据库模式由 spring/hibernate 自动生成。

问题:

我正在尝试保留从外部 REST 资源检索到的 Person 的新实例。当我使用注入PersonRepository 扩展JpaRepository 并调用personRepository.save(person) 的spring-boot 时,出现以下异常:

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2018-06-07 10:36:30,383 ERROR SpringApplication - Application run failed
java.lang.IllegalStateException: Failed to execute CommandLineRunner
    ... 6 more
Caused by: org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [fk_rmnbkmxocx4dcayhiyr1wxypc]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
    ... 23 more
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
    ... 56 more
Caused by: org.postgresql.util.PSQLException: ERROR: insert or update on table "person" violates foreign key constraint "fk_rmnbkmxocx4dcayhiyr1wxypc"
  Detail: Key (current_site_id)=(738) is not present in table "site".
    ... 62 more

Person

id [PK] | batch_id | brigade_id | call_sign | lat | lon | incident_id | type_id | current_site_id | home_site_id | relocation_site_id | status_id | first_name | surname

Site 列:

id [PK] | batch_id | brigade_id | call_sign | lat | lon | location | type_id

问题:

应该进行哪些更改才能使持久化工作。我的第一个假设是架构需要更改,但我不确定它会以哪种方式做到这一点,也不知道如何使用注释来实现。

非常感谢。

编辑: 澄清一下,我希望能够在持久化 Person 对象时持久化 Site 对象,而不是预先持久化任何东西以准备 @987654338 @。

我的一个想法是使用远程服务器的主键 (id) 作为备用键,并使用 @GeneratedValue 生成我自己的键,但我认为这也可能导致相同的问题。

有人知道为什么CascadeType.PERSIST 在这种情况下不起作用吗?

【问题讨论】:

    标签: java postgresql jpa foreign-keys


    【解决方案1】:

    Site 表中似乎没有 id = 738 的行,因此您无法将该行插入到 Person 表中。

    您应该首先尝试在 Site 表中插入一行 id 为 738 的行,然后才尝试插入到 Person 表中。

    【讨论】:

    • 我正在通过 REST 服务器以 XML 格式检索 Person 对象。此 XML 包含 Site 对象本身,以及它们与 Person 的关系。为了使用这种方法,我必须保留这个 XML 的对象树中包含的每个对象,其中有很多。我希望持久化将级联到Site 对象?
    猜你喜欢
    • 2012-12-17
    • 2011-12-22
    • 2011-07-16
    • 1970-01-01
    • 2016-06-10
    • 2018-11-16
    • 2011-01-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多