Make PersistenceManager Less Error Prone #83

Merged
delvh merged 2 commits from b/crashing-server-with-invalid-objects into develop 2020-10-07 22:13:43 +02:00
Showing only changes of commit 858662ba17 - Show all commits

View File

@ -28,15 +28,13 @@ public final class PersistenceManager {
* @since Envoy Server Standalone v0.1-alpha
*/
private PersistenceManager() {
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
transaction.begin();
Runtime.getRuntime().addShutdownHook(new Thread(() -> transaction(() -> {
ConnectionManager.getInstance()
.getOnlineUsers()
.stream()
.map(this::getUserByID)
.forEach(user -> { user.setStatus(UserStatus.OFFLINE); user.setLastSeen(Instant.now()); entityManager.merge(user); });
transaction.commit();
}));
})));
}
/**
@ -239,10 +237,7 @@ public final class PersistenceManager {
c2.getContacts().add(c1);
// Synchronize changes with the database
transaction.begin();
entityManager.merge(c1);
entityManager.merge(c2);
transaction.commit();
transaction(() -> { entityManager.merge(c1); entityManager.merge(c2); });
}
/**
@ -254,47 +249,33 @@ public final class PersistenceManager {
return entityManager.createNamedQuery(User.findContacts).setParameter("user", user).getResultList();
}
private void persist(Object obj) {
private void persist(Object obj) { transaction(() -> entityManager.persist(obj)); }
private void merge(Object obj) { transaction(() -> entityManager.merge(obj)); }
private void remove(Object obj) { transaction(() -> entityManager.remove(obj)); }
/**
* Performs a transaction with the given Runnable, that should somewhere call
* {@link EntityManager}.
*
* @param entityManagerRelatedAction the action that changes something in the
* database
* @since Envoy Server v0.3-beta
*/
private void transaction(Runnable entityManagerRelatedAction) {
try {
transaction.begin();
entityManager.persist(obj);
entityManagerRelatedAction.run();
transaction.commit();
// Last transaction threw an error resulting in the transaction not being closed
} catch (final IllegalStateException e) {
if (transaction.isActive()) {
transaction.rollback();
persist(obj);
}
}
}
private void merge(Object obj) {
try {
transaction.begin();
entityManager.merge(obj);
transaction.commit();
// Last transaction threw an error resulting in the transaction not being closed
} catch (final IllegalStateException e) {
if (transaction.isActive()) {
transaction.rollback();
merge(obj);
}
}
}
private void remove(Object obj) {
try {
transaction.begin();
entityManager.remove(obj);
transaction.commit();
// Last transaction threw an error resulting in the transaction not being closed
} catch (final IllegalStateException e) {
if (transaction.isActive()) {
transaction.rollback();
remove(obj);
transaction.begin();
entityManagerRelatedAction.run();
transaction.commit();
}
}
}