In order to keep transfered data small I created two entities for my files in the database. The fileheader
to keep some general information about the files and the fileblob
, including fileId
and the blob. Often, I only need to ask for general fileinformations
.
So I need to load the fileblobs
lazily.
As I learned in this discussion and that discussion. this could be achieved with optional = false
. It works perfect to load the fileblobs
lazily. Unfortunately it affects save by cascade.
So here is my attribute in the Fileh.class
for the blob:
@OneToOne(mappedBy = "fileh", targetEntity = Fileblob.class, fetch = FetchType.LAZY, optional = false)
@org.hibernate.annotations.Cascade({ org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.LOCK })
private Fileblob fileblob;
If I now save a fileh
with attached fileblob
, this error is thrown:
org.hibernate.id.IdentifierGenerationException: null id generated for:class Fileblob
if i switch from id-generation strategy "identity" to "increment" this error is thrown:
ERROR SqlExceptionHelper:147 - Cannot add or update a child row: a foreign key constraint fails (`CORE`.`FILEBLOB`, CONSTRAINT
FKFILEBLOB412557
FOREIGN KEY (ID
) REFERENCESFILEH
(ID
)) Query is: insert into CORE.FILEBLOB
(FILEBLOB
,ID
) values (?, ?)
So there is a problem with generating the id... If i now turn off save by cascade my attribute looks like this.
@OneToOne(mappedBy = "fileh", targetEntity = Fileblob.class, fetch = FetchType.LAZY, optional = false)
private Fileblob fileblob;
In order to save now, I have to call
persistentSession.saveOrUpdate(fileh);
persistentSession.saveOrUpdate(fileblob);
Is this not just what CascadeType.SAVE_UPDATE
is supposed to do?
Why is this working for "manual cascading" but not automatically?
P.s.: To complete my example here the counterpart in fileblob.class
@PrimaryKeyJoinColumn
@OneToOne(targetEntity=Fileh.class, fetch=FetchType.LAZY)
@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.LOCK})
@JoinColumns({ @JoinColumn(name="`ID`", referencedColumnName="`ID`", unique=true, nullable=false) })
private Fileh fileh;
@Column(name="`ID`", nullable=false, insertable=false, updatable=false, unique=true)
@Id
@GeneratedValue(generator="FILEBLOB_FILEHID_GENERATOR")
@org.hibernate.annotations.GenericGenerator(name="FILEBLOB_FILEHID_GENERATOR", strategy="foreign", parameters=@org.hibernate.annotations.Parameter(name="property", value="fileh"))
private int filehId;