Skip to content

Commit

Permalink
Fix HibernateException: could not re-associate uninitialized transient
Browse files Browse the repository at this point in the history
... collection". This is caused because the object being saved has a
lazy-loading collection that is not loaded, but it is no longer attached
to a session. The solution is to merge (re-attach) the object to the
current session before doing something with it again.

The merge operation cannot modify the current object, but returns a new
(proxy) object that must be used from now on. To make this
counterintuitive behaviour of the API more obvious, the CheckReturnValue
annotation was introduced, which is evaluated by Spotbugs, which results
in a Spotbugs alert if it is ignored.
  • Loading branch information
matthias-ronge committed Jul 8, 2024
1 parent 83c912c commit 955a03a
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 1 deletion.
6 changes: 6 additions & 0 deletions Kitodo-DataManagement/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jcache</artifactId>
</dependency>
<dependency>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-annotations</artifactId>
<version>${spotbugs-maven-plugin.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

package org.kitodo.data.database.persistence;

import edu.umd.cs.findbugs.annotations.CheckReturnValue;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
Expand Down Expand Up @@ -163,6 +165,17 @@ public void evict(T baseBean) {
evictObject(baseBean);
}

/**
* Merge given bean object.
*
* @param baseBean
* bean to Merge
*/
@CheckReturnValue
public T merge(T baseBean) {
return mergeObject(baseBean);
}

/**
* Retrieves BaseBean objects from database by given query.
*
Expand Down Expand Up @@ -413,6 +426,20 @@ private void evictObject(T object) {
}
}

/**
* Merge object into the session.
*
* @param object
* to be associated with the session
*/
@SuppressWarnings("unchecked")
@CheckReturnValue
private T mergeObject(T object) {
try (Session session = HibernateUtil.getSession()) {
return (T) session.merge(object);
}
}

/**
* Refresh object associated with the session.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1877,9 +1877,10 @@ public static void deleteProcess(Process processToDelete) throws DataException,
parent.getChildren().remove(processToDelete);
processToDelete.setParent(null);
MetadataEditor.removeLink(parent, processToDelete.getId());
ServiceManager.getProcessService().save(processToDelete);
processToDelete = ServiceManager.getProcessService().merge(processToDelete);
ServiceManager.getProcessService().save(parent);
}
processToDelete = ServiceManager.getProcessService().merge(processToDelete);
List<Batch> batches = new CopyOnWriteArrayList<>(processToDelete.getBatches());
for (Batch batch : batches) {
batch.getProcesses().remove(processToDelete);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

package org.kitodo.production.services.data.base;

import io.reactivex.annotations.CheckReturnValue;

import java.util.EnumMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -170,6 +172,11 @@ public void evict(T baseBean) {
this.dao.evict(baseBean);
}

@CheckReturnValue
public T merge(T baseBean) {
return this.dao.merge(baseBean);
}

/**
* Refresh given bean object.
*
Expand Down

0 comments on commit 955a03a

Please sign in to comment.