如何使用JPA持久保存具有单个类型的多个字段的实体?

时间:2018-06-07 09:58:35

标签: java postgresql jpa foreign-keys

背景

我有一个抽象类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的{​​{1}}具体子类。

MobileResource

相关模块是使用 spring-data-jpa postgres 数据库的 spring-boot 应用程序。数据库模式由spring / hibernate自动生成。

问题:

我正在尝试保留从外部REST资源检索的@Entity public class Person extends MobileResource implements Serializable { private String firstName; private String surname; // constructors, getters, setters } 的新实例。当我使用弹簧引导注入Person扩展PersonRepository并调用JpaRepository时,我得到以下异常:

personRepository.save(person)

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 对象时保留Site对象,而不是预先准备任何内容对于Person

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

有人知道为什么@GeneratedValue在这种情况下不起作用吗?

1 个答案:

答案 0 :(得分:0)

似乎Site表中没有id = 738的行,所以你不能将该行插入Person表。

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