Issue
The problem
Im having two entities. One is called EntityPojo and the other one is called ChunkPojo. The entityPojo does not know about the ChunkPojo. The ChunkPojo has a 1:1 reference to the EntityPojo. First i save the EntityPojo, then i save the ChunkPojo.
At the time i save the ChunkPojo, hibernate tries to insert the referenced 1:1 EntityPojo which results in an duplicate key exception. But... cascading is disabled, this should NOT happen.
The code
/** The base for all database objects
*/
@MappedSuperclass
public abstract class DatabaseObject extends Component{
@Id
public Long id;
@MapsId
@JoinColumn(name = "id")
@OneToOne(cascade = {})
public EntityPojo entityPojo;
}
@Entity
@Table(name = "entity")
@Access(AccessType.FIELD)
public class EntityPojo {
@Id public long id;
public long version;
public String tag;
public String typeID;
public EntityPojo() { }
}
/**
* A chunk which extends DatabaseObject.
*/
@Entity
@Table(name = "chunk", uniqueConstraints = {@UniqueConstraint(columnNames={"x", "y"})}, indexes = {@Index(columnList = "x,y")})
@Access(value = AccessType.FIELD)
@SelectBeforeUpdate(value = false)
public class ChunkPojo extends DatabaseObject {
public int x;
public int y;
public Date createdOn;
}
public static void main(String[] args){
var enitity = new EntityPojo();
enitity.id = 1;
enitity.tag = "player";
enitity.typeID = "1:1";
var chunk = new ChunkPojo();
chunk.x = 10;
chunk.y = 11;
chunk.entityPojo = enitity;
chunk.id = enitity.id;
syncDatabase.save(enitity); // Just calls session.persist - works fine
syncDatabase.save(chunk); // Also calls session.persist - exception
}
Question
Why does hibernate try to insert the referenced 1:1 relation when i clearly did not used any cascading here ? And how can i prevent it from happening ?
Glad for any help on this topic ! It drives me crazy ! Thanks !
Solution
I think what's happening is that the @MapsId
annotation tells Hibernate to take the ID of chunk
and map it to the ID field of entity
. So when you save chunk
it automatically gets cascade persisted, even though you haven't explicitly told it to do so.
Answered By - David DeMar
Answer Checked By - Clifford M. (JavaFixing Volunteer)