简体   繁体   中英

How to persist an entity with multiple fields of a single type using JPA?

Background:

I have an abstract class MobileResource , which contains three fields each of type Site . These fields can, and often do contain the same object.

@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
}

I also have a Person concrete subclass of MobileResource .

@Entity
public class Person extends MobileResource implements Serializable {

    private String firstName;
    private String surname;

    // constructors, getters, setters
}

The module in question is a spring-boot application using spring-data-jpa a postgres database. The database schema is autogenerated by spring/hibernate.

Problem:

I'm trying to persist a new instance of Person , retrieved from an external REST resource. When I use a spring-boot injected PersonRepository extending JpaRepository , and call personRepository.save(person) , I get the following exception:

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 Columns :

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 Columns:

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

Question:

What changes should be made in order for the persist to work. My first assumption would be that the schema needs to change, but I'm not sure in which way it would do that, nor how to achieve that using annotations.

Many thanks in advance.

Edit: Just to clarify, I would like to be able to persist the Site object when I persist the Person object, instead of pre-persisting anything in preparation for the Person .

One idea that I had was to use the remote server's primary key ( id ) as a an alternate key and generate my own key using @GeneratedValue but I think that might also cause the same issues.

Does anybody know why CascadeType.PERSIST doesn't work in this case?

It seems that there is no row in Site table where id = 738, so you can't insert that row into Person table.

You should first try to insert a row into Site table with id as 738, and only then try to insert into Person table.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM