TLDR: Switched Hibernate Versions from 3. to 5.. Now, OneToOne Relationship with shared primary key that is only mapped in one class persists the two entities in the wrong order, violating a foreign key constraint. How to change the order?
In the process of migrating from a jboss 7 instance to a current wildfly, my team also had to update our hibernate version from 3 to 5.3.10.
While doing that, I encountered a problem with one of our entity constructs in which I have hit a brick wall.
The general concept is the following:
I have a main entity class that has multiple "modules" as attritubes which share the primary key of the main entity class. These modules are entity classes themselves and hold various logic and further relationships. However, the module entities don't have any other persistent attributes. They hold no reference to the main entity class either.
In that regard, it is (in the object oriented world of java) a unidirectional relationship with a shared primary key (I understand the shared primary key makes it bidirectional for the database).
The Java Code would be something like this:
@Entity(name = "mainEntity")
@Table(name = "main_entity")
public class MainEntity {
// Business Logic ...
@Id
private Long id;
@OneToOne( targetEntity = ModuleA.class, cascade = CascadeType.ALL, optional = false,
orphanRemoval = true )
@PrimaryKeyJoinColumn( name = "id", referencedColumnName = "id" )
private ModuleA moduleA;
// More Modules...
}
@Entity(name=moduleA)
@Table(name=module_a)
public class ModuleA {
@Id
private Long id;
// other relationships to entirely different entities,
// but no reference to mainEntity or other "modules"
}
In our previous system, this worked just fine. When using something like
entityManager.persist(mainEntity);
The modules would get persisted first, and afterwards the mainEntity.
However, with our updated hibernate version, this is not what happens. Using this mapping, the insertion order is reversed and the entityManager will try to persist the mainEntity first. This results in a violation of a foreign key constraint that should prevent inconsistencies between the tables.
On a side note: I tried changing
@PrimaryKeyJoinColumn(...)
into
@MapsId(value="id")
This actually changed the persitence order around correctly. However, doing this, caused hibernate to no longer properly understand the shared primary key -> While persisting worked for some reason,
entityManager.find(ModuleA.class,primaryKey);
did not work, yielding errors like "column mainEntity.moduleA_id does not exist."
Is there a way you can think of to express the need to persist the modules first, as Hibernate 3 did for us?
I'll greatly appreciate any help.
PS: This is my first question, if there's more information required, or if there's a problem with the formulation, do tell, please. :)