Reputation: 6287
I'm trying to set up a OneToOne
relationship between two entities that share the same PK:
+----------------------------------+ +----------------+-----------------+
| Item | | Stats |
+----------------+-----------------+ +----------------+-----------------+
| reference (PK) | other data... | | reference (PK) | other data... |
+----------------+-----------------+ +----------------+-----------------+
| ABCD | ... | | ABCD | ... |
| XYZ | ... | | XYZ | ... |
+----------------+-----------------+ +----------------+-----------------+
where Stats.reference
is a FK to Item.reference
:
alter table Stats
add constraint FK_8du3dv2q88ptdvthk8gmsipsk
foreign key (reference)
references Item;
This structure is generated from the following annotaded classes:
@Entity
public class Item {
@Id
private String reference;
@OneToOne(mappedBy = "item", optional = false)
@Cascade({CascadeType.SAVE_UPDATE})
@Fetch(FetchMode.SELECT)
private Stats stats;
// ...
}
@Entity
public class Stats {
@Id
@OneToOne
@JoinColumn(name = "reference")
@Fetch(FetchMode.SELECT)
private Item item;
// ...
}
A new Item
is creted as follows:
Item item = new Item();
item.setReference("ABC");
Stats stats = new Stats();
stats.setItem(item);
item.setStats(stats);
session.save(item);
My problem is when I do session.save(item)
the INSERT statements order are wrong.
Hibernate first tries to insert into Stats
table instead of Item
, resulting in a FK constraint error.
How can I solve this issue? Thanks in advance.
Upvotes: 6
Views: 2694
Reputation: 6287
The @JoinColumn
annotation in Stats
entity isn't complete, the attribute referencedColumnName
must be specified.
public abstract java.lang.String referencedColumnName
(Optional) The name of the column referenced by this foreign key column.
@Entity
public class Stats {
@Id
@OneToOne
@JoinColumn(name = "reference", referencedColumnName = "reference")
@Fetch(FetchMode.SELECT)
private Item item;
// ...
}
Upvotes: 0
Reputation: 2488
since you have one to one relationship between item and state and item has stats key as FK, and here you entity object should look like this
Item{
@OneToOne
@JoinColumn(name = "stat_id", nullable=false) //incase if you allow null
private stats stats
}
in stats entity no need to add relation annotation, since we defined in Item
while saving , you just save item entity, stats also get inserted
item.setStats(stats);
session.save(item);
in case if you want to save stats separately and items separately,
then you have define cascade type as DETACH for stats
Class Item{
@OneToOne(cascade=CascadeType.DETACH)
@JoinColumn(name = "stat_id", nullable=false) //incase if you allow null
private stats stats
}
Upvotes: 0
Reputation: 1164
Since your class Stats owns the association, try to do :
stats.setItem(item);
session.save(stats)
Upvotes: 4