Make PersistenceManager Less Error Prone (#83)
Reviewed-on: https://git.kske.dev/zdm/envoy/pulls/83 Reviewed-by: kske <kai@kske.dev> Reviewed-by: DieGurke <maxi@kske.dev>
This commit is contained in:
		@@ -28,15 +28,13 @@ public final class PersistenceManager {
 | 
				
			|||||||
	 * @since Envoy Server Standalone v0.1-alpha
 | 
						 * @since Envoy Server Standalone v0.1-alpha
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	private PersistenceManager() {
 | 
						private PersistenceManager() {
 | 
				
			||||||
		Runtime.getRuntime().addShutdownHook(new Thread(() -> {
 | 
							Runtime.getRuntime().addShutdownHook(new Thread(() -> transaction(() -> {
 | 
				
			||||||
			transaction.begin();
 | 
					 | 
				
			||||||
			ConnectionManager.getInstance()
 | 
								ConnectionManager.getInstance()
 | 
				
			||||||
				.getOnlineUsers()
 | 
									.getOnlineUsers()
 | 
				
			||||||
				.stream()
 | 
									.stream()
 | 
				
			||||||
				.map(this::getUserByID)
 | 
									.map(this::getUserByID)
 | 
				
			||||||
				.forEach(user -> { user.setStatus(UserStatus.OFFLINE); user.setLastSeen(Instant.now()); entityManager.merge(user); });
 | 
									.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);
 | 
							c2.getContacts().add(c1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Synchronize changes with the database
 | 
							// Synchronize changes with the database
 | 
				
			||||||
		transaction.begin();
 | 
							transaction(() -> { entityManager.merge(c1); entityManager.merge(c2); });
 | 
				
			||||||
		entityManager.merge(c1);
 | 
					 | 
				
			||||||
		entityManager.merge(c2);
 | 
					 | 
				
			||||||
		transaction.commit();
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
@@ -254,47 +249,33 @@ public final class PersistenceManager {
 | 
				
			|||||||
		return entityManager.createNamedQuery(User.findContacts).setParameter("user", user).getResultList();
 | 
							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 {
 | 
							try {
 | 
				
			||||||
			transaction.begin();
 | 
								transaction.begin();
 | 
				
			||||||
			entityManager.persist(obj);
 | 
								entityManagerRelatedAction.run();
 | 
				
			||||||
			transaction.commit();
 | 
								transaction.commit();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Last transaction threw an error resulting in the transaction not being closed
 | 
								// Last transaction threw an error resulting in the transaction not being closed
 | 
				
			||||||
		} catch (final IllegalStateException e) {
 | 
							} catch (final IllegalStateException e) {
 | 
				
			||||||
			if (transaction.isActive()) {
 | 
								if (transaction.isActive()) {
 | 
				
			||||||
				transaction.rollback();
 | 
									transaction.rollback();
 | 
				
			||||||
				persist(obj);
 | 
									transaction.begin();
 | 
				
			||||||
			}
 | 
									entityManagerRelatedAction.run();
 | 
				
			||||||
		}
 | 
									transaction.commit();
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	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);
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user