I've got a situation where we've got a JPA entity TableA that one-to-many joins to TableB and one-to-one joins to TableC & one-to-zero-or-one joins to TableD.
The problem is that when there exists an entry in table_b with a value in table_c_id that doesn't also exist in table_d, when I try to do a get on table_a, I get a 404 instead of the value with a null for table_d.
my entities for table_b and table_d look like this:
@Entity
@Table(name = "table_b")
@IdClass(TableAAndTableCCompositePrimaryKey.class)
public class TableB {
@Id
@Column(name = "table_a_id")
@Type(type = "uuid-char")
private UUID tableAId;
@Id
@Column(name = "table_c_id")
@Type(type = "uuid-char")
private UUID tableCId;
@OneToOne
@JoinColumn(name = "table_c_id", insertable = false, updatable = false)
private TableC tableC;
@OneToOne
@JoinColumn(name = "table_c_id", insertable = false, updatable = false)
private TableD tableD;
}
@Entity
@Table(name = "table_d")
public class TableD {
@Id
@Column(name = "table_c_id")
@Type(type = "uuid-char")
private UUID tableCId;
}
I was unable to put a FK on table_d because table_d could have a value for table_c_id that isn't in table_b.
I'f i've got the rows:
table_a
aaa
bbb
table_b
aaa,ccc
aaa,ddd
table_c
ccc
ddd
table_d
ddd
and I try and grab TableA where tableAId = aaa, I get back a 404, but if I get TableA by tableAId = bbb it works fine. Any time table_b has a value for table_c_id that doesn't exist I don't get back table_a.
Surprisingly, if I change around the joins so that table_d joins off table_c, which I am able to create a foreign key constraint on, it fixes the issue.
What I'm wondering is why didn't the first situation work? Does JPA require a foreign key relation between two joining entities?
CodePudding user response:
For this purpose, Hibernate has the @NotFound
annotation which allows you to control the behavior, when a foreign key column like table_b.table_c_id
has a value that has no matching target row.
By default, JPA has no such mechanism and thus expects a well formed foreign key relationship. You could theoretically make it work with a @SecondaryTable
, though that would mean you can't have a TableD
entity.