Problem
Im using hibernate 5.4.11 core and when i try to update large amounts of entities i run into that issue right here. It looks like an hibernate internal exception.
Update
I tested it with hibernate 5.4.23, the same exception occured. I also updated my “mysql connector” to the latest version “8.0.22” and it didnt worked either, the same exception.
Describtion
This is how i update my entities, it runs in another thread, which should not be the problem here… its basically a own thread for database operations, during that operation no other database operations are running.
// Run the database operation for updating the entities async in a new thread, return updated entities once done
return CompletableFuture.runAsync(() -> {
var session = database.openSession();
session.beginTransaction();
try {
// Save identities first
for (var identity : identities)
session.update(identity);
// Update components, each component-type
for(var insertedClass : insertationOrder)
for (var hbc : componentsPerType.get(insertedClass))
session.update(hbc);
session.flush();
session.clear();
session.getTransaction().commit();
} catch (Exception e){
var messageComposer = new ExceptionMessageComposer(e);
GameExtension.getInstance().trace("Update : "+messageComposer.toString());
session.getTransaction().rollback();
}
session.close();
}).thenApply(v -> entities);
The class i try to save
@Entity
@Table(name = "chunk", uniqueConstraints = {@UniqueConstraint(columnNames={"x", "y"})}, indexes = {@Index(columnList = "x,y")})
@Access(value = AccessType.FIELD)
@SelectBeforeUpdate(false)
public class Chunk extends HibernateComponent{
public int x;
public int y;
public Date createdOn;
@OneToMany(fetch = FetchType.EAGER)
@JoinTable(name = "chunk_identity", joinColumns = @JoinColumn(name = "identity_id"), inverseJoinColumns = @JoinColumn(name = "id"), inverseForeignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
@Fetch(FetchMode.JOIN)
@BatchSize(size = 50)
public Set<Identity> inChunk = new LinkedHashSet<>();
@Transient
public Set<ChunkLoader> loadedBy = new LinkedHashSet<>();
public Chunk() {}
public Chunk(int x, int y, Date createdOn) {
this.x = x;
this.y = y;
this.createdOn = createdOn;
}
}
@Entity
@Table(name = "location")
@Access(AccessType.FIELD)
public class Transform extends HibernateComponent {
@Embedded
public Vector2 position = new Vector2();
@ManyToOne
@JoinColumn(name = "chunk_id", referencedColumnName = "identity_id", updatable = false)
@Fetch(FetchMode.JOIN)
public Chunk chunk;
@Transient
public Vector2 previousPos = new Vector2();
public Transform() {}
public Transform(Vector2 position) { this.position = position; }
public Transform(Vector2 position, Chunk chunk) { this.position = position; this.chunk = chunk; }
}
The exception i get
19:29:05,126 INFO [ForkJoinPool.commonPool-worker-19] Extensions - {Game}: Update : java.util.ConcurrentModificationException:
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Exception: java.util.ConcurrentModificationException
Message: *** Null ***
+--- --- ---+
Stack Trace:
+--- --- ---+
java.base/java.util.HashMap$HashIterator.nextNode(HashMap.java:1493)
java.base/java.util.HashMap$KeyIterator.next(HashMap.java:1516)
org.hibernate.persister.collection.AbstractCollectionPersister.insertRows(AbstractCollectionPersister.java:1555)
org.hibernate.action.internal.CollectionUpdateAction.execute(CollectionUpdateAction.java:89)
org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604)
org.hibernate.engine.spi.ActionQueue.lambda$executeActions$1(ActionQueue.java:478)
java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:684)
org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:475)
org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:348)
org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:40)
org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:102)
org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1356)
org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1343)
com.parallelorigin.persistence.database.ECSDatabase.lambda$updateEntities$16(ECSDatabase.java:242)
java.base/java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1736)
java.base/java.util.concurrent.CompletableFuture$AsyncRun.exec(CompletableFuture.java:1728)
java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177)
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Anyone having an idea why hibernate throws that internal exception and what i could do to solve this issue ?