Hibernate cannot find the entity it's about to delete when I'm using the delete_orphan annotation in combination with an updatable foreign key. Both entities are versioned for optimistic locking. When I inspect hibernates sql it seems it first updates the child entity by setting to foreign key to null. Afterwards the delete_orphan is doing it's work with the resulting delete statement. The problem is that the update on the child entity increases the version nr of this child entity on the database but not on the hibernate entity. And so the next delete statement will fail cause it's using the old version nr. Here's the sql hibernate generates:
14:03:18,012 INFO [STDOUT] 14:03:18,012 DEBUG [SQL]
update
BLOKKEN
set
APPLICATIE_WIJZIGING=?,
GEBRUIKER_WIJZIGING=?,
TIJDSTIP_WIJZIGING=?,
versie=?,
BRON_CREATIE=?,
DAGDEEL=?,
TIJDSTIP_TOT=?,
TIJDSTIP_VAN=?,
DATUM=?,
MLOC_GID=?,
STATUS=?,
REDEN_STATUS=?,
TOELICHTING_STATUS=?
where
BLK_GID=?
and versie=?
14:03:18,028 INFO [STDOUT] 14:03:18,028 DEBUG [SQL]
update
SUBBLOKKEN
set
BLK_GID=null
where
BLK_GID=?
14:03:18,044 INFO [STDOUT] 14:03:18,044 DEBUG [SQL]
delete
from
SUBBLOKKEN
where
SBLK_GID=?
and versie=?
What happens in the code: a detached Blok entity (that's coming from a client front-end, and where a SubBlok entity is removed from the onytomany assocation) is saved using JPA's merge and flush methods.
I have a unidirectional onetomany association with the following annotation mappings.
Parent entity:
Code:
@Entity
@Table(name = "BLOKKEN")
@AttributeOverride(name = "id", column = @Column(name = "BLK_GID", unique = true, nullable = false, insertable = true, updatable = false, columnDefinition = "RAW(16)"))
public class Blok extends EntityWithRawId {
.
.
.
@OneToMany(fetch = FetchType.LAZY, cascade={CascadeType.ALL})
@JoinColumn(name = "BLK_GID",nullable=true,insertable=true,updatable=true)
@Cascade(value = org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
@Cache (region="distributed", usage=CacheConcurrencyStrategy.READ_WRITE)
@Fetch(FetchMode.SUBSELECT)
@Sort(type = SortType.NATURAL)
public SortedSet<SubBlok> getSubBlokken() {
return subBlokken;
}
public void setSubBlokken(SortedSet<SubBlok> subBlokken) {
this.subBlokken = subBlokken;
}
.
.
.
The child entity:
Code:
@Entity
@Table(name = "SUBBLOKKEN")
@AttributeOverride(name = "id", column = @Column(name = "SBLK_GID", unique = true, nullable = false, insertable = true, updatable = false, columnDefinition = "RAW(16)"))
public class SubBlok extends EntityWithRawId implements Comparable<SubBlok> {
.
.
.
Setting updatable=false on the joincolumn does fix this problem (cause it won't do the update statement anymore) however that's no option because the combination of nullable=true and updatable=false makes it impossible for hibernate to persist the relationship (the foriegn key will stay null because it's can't be updated).