简体   繁体   中英

Correct way to check for foreign key constraint violation in Hibernate?

I have two tables that already exist inside postgres, lets call the Table A and Table B. One column of Table B has a foreign key constraint in that it has to be the primary key of Table A. Thus there is a many-to-one relationship between B and A, where multiple records in Table B correspond to one record of Table A.

The Entity for both these tables are defined as follows.

public class TableA implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id")
private Long userId;

@Column(name = "name")
private String name;

@Column(name = "email")
private String email;

@Column(name = "phone_number")
private String phoneNumber;
}

TableB's entity is defined as follows:

public class Shots implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "item_id")
private Long itemId;

@Column(name = "user_id")
private Long userId;
}

Where userId is the foreign key mapping to the primary key user_id in Table A. These constraints have already been defined in the underlying postgres database, so i didn't consider using the @ManyToOne annotation relationship (still trying to wrap my head around it).

The way i currently handle the case when a foreign key constraint violation occurs is by doing the following:

try {
        tableBrepository.save(newShot);
    } catch (ConstraintViolationException ex) {
        logger.error("Violating foreign key constraint" + ex.getMessage());
    }

My question is, is there a better way to check for this violation? Is there anything i can do to generally better structure the foreign key constraint in Spring Data JPA?

Thus there is a many-to-one relationship between B and A, where multiple records in Table B correspond to one record of Table A.

This kind of stuff in JPA entities is handled with @ManyToOne annotation. You usually do not refer to any id field directly but tell JPA what there should be. So in your class TableB (or should I call it... Shots?) should be something like:

@ManyToOne
private TableA tableA;

// and get rid of this
// @Column(name = "user_id")
// private Long userId;

And optionally - so not necessarily - you could have, in your TableA:

@OneToMany
private List<TableB> tableBsOrShouldICallYouShots;

I am not sure what is your actual problem but when setting and referring to id fields directly might cause your difficulties.

Now if you -for example- use repository to find some TableB you can then after that just do

tableB.getTableA()

And when saving you would before that do:

tableB.setTableA(somSortOftableA);
// so not tableB.setUserId(someLongIdFOrtableA);

Now the point is that there is no problem with referential integrity because you do not need to know any IDs and you cannot set any wrong ID. Unless you first need to fetch TableA by id before setting it to TableB but in that case you would still not set any IDs.

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