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
FKFILEBLOB412557FOREIGN 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;