From 2e475c35ccf8037d3259d68c0d66cece83946dbe Mon Sep 17 00:00:00 2001 From: Athou Date: Fri, 12 Dec 2014 08:57:50 +0100 Subject: [PATCH] unit of work refactoring --- .../com/commafeed/backend/dao/UnitOfWork.java | 33 ++++++---- .../backend/feed/FeedRefreshTaskGiver.java | 7 +- .../backend/feed/FeedRefreshUpdater.java | 14 +--- .../service/DatabaseCleaningService.java | 43 +++--------- .../backend/service/StartupService.java | 13 ++-- .../frontend/servlet/CustomCssServlet.java | 15 +---- .../frontend/servlet/NextUnreadServlet.java | 66 ++++++++----------- 7 files changed, 67 insertions(+), 124 deletions(-) diff --git a/src/main/java/com/commafeed/backend/dao/UnitOfWork.java b/src/main/java/com/commafeed/backend/dao/UnitOfWork.java index 27f8d347..d4f2ac41 100644 --- a/src/main/java/com/commafeed/backend/dao/UnitOfWork.java +++ b/src/main/java/com/commafeed/backend/dao/UnitOfWork.java @@ -5,17 +5,26 @@ import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.context.internal.ManagedSessionContext; -public abstract class UnitOfWork { +public class UnitOfWork { - private SessionFactory sessionFactory; - - public UnitOfWork(SessionFactory sessionFactory) { - this.sessionFactory = sessionFactory; + @FunctionalInterface + public static interface SessionRunner { + public void runInSession(); } - protected abstract T runInSession() throws Exception; + @FunctionalInterface + public static interface SessionRunnerReturningValue { + public T runInSession(); + } - public T run() { + public static void run(SessionFactory sessionFactory, SessionRunner sessionRunner) { + run(sessionFactory, () -> { + sessionRunner.runInSession(); + return null; + }); + } + + public static T run(SessionFactory sessionFactory, SessionRunnerReturningValue sessionRunner) { final Session session = sessionFactory.openSession(); if (ManagedSessionContext.hasBind(sessionFactory)) { throw new IllegalStateException("Already in a unit of work!"); @@ -25,11 +34,11 @@ public abstract class UnitOfWork { ManagedSessionContext.bind(session); session.beginTransaction(); try { - t = runInSession(); + t = sessionRunner.runInSession(); commitTransaction(session); } catch (Exception e) { rollbackTransaction(session); - this. rethrow(e); + UnitOfWork. rethrow(e); } } finally { session.close(); @@ -38,14 +47,14 @@ public abstract class UnitOfWork { return t; } - private void rollbackTransaction(Session session) { + private static void rollbackTransaction(Session session) { final Transaction txn = session.getTransaction(); if (txn != null && txn.isActive()) { txn.rollback(); } } - private void commitTransaction(Session session) { + private static void commitTransaction(Session session) { final Transaction txn = session.getTransaction(); if (txn != null && txn.isActive()) { txn.commit(); @@ -53,7 +62,7 @@ public abstract class UnitOfWork { } @SuppressWarnings("unchecked") - private void rethrow(Exception e) throws E { + private static void rethrow(Exception e) throws E { throw (E) e; } diff --git a/src/main/java/com/commafeed/backend/feed/FeedRefreshTaskGiver.java b/src/main/java/com/commafeed/backend/feed/FeedRefreshTaskGiver.java index 96e264da..0a5fdd4d 100644 --- a/src/main/java/com/commafeed/backend/feed/FeedRefreshTaskGiver.java +++ b/src/main/java/com/commafeed/backend/feed/FeedRefreshTaskGiver.java @@ -68,12 +68,7 @@ public class FeedRefreshTaskGiver implements Managed { public void run() { while (!executor.isShutdown()) { try { - FeedRefreshContext context = new UnitOfWork(sessionFactory) { - @Override - protected FeedRefreshContext runInSession() throws Exception { - return queues.take(); - } - }.run(); + FeedRefreshContext context = UnitOfWork.run(sessionFactory, () -> queues.take()); if (context != null) { feedRefreshed.mark(); worker.updateFeed(context); diff --git a/src/main/java/com/commafeed/backend/feed/FeedRefreshUpdater.java b/src/main/java/com/commafeed/backend/feed/FeedRefreshUpdater.java index 7139ffc0..a36d4b77 100644 --- a/src/main/java/com/commafeed/backend/feed/FeedRefreshUpdater.java +++ b/src/main/java/com/commafeed/backend/feed/FeedRefreshUpdater.java @@ -120,12 +120,7 @@ public class FeedRefreshUpdater implements Managed { if (!lastEntries.contains(cacheKey)) { log.debug("cache miss for {}", entry.getUrl()); if (subscriptions == null) { - subscriptions = new UnitOfWork>(sessionFactory) { - @Override - protected List runInSession() throws Exception { - return feedSubscriptionDAO.findByFeed(feed); - } - }.run(); + subscriptions = UnitOfWork.run(sessionFactory, () -> feedSubscriptionDAO.findByFeed(feed)); } ok &= addEntry(feed, entry, subscriptions); entryCacheMiss.mark(); @@ -190,12 +185,7 @@ public class FeedRefreshUpdater implements Managed { locked1 = lock1.tryLock(1, TimeUnit.MINUTES); locked2 = lock2.tryLock(1, TimeUnit.MINUTES); if (locked1 && locked2) { - boolean inserted = new UnitOfWork(sessionFactory) { - @Override - protected Boolean runInSession() throws Exception { - return feedUpdateService.addEntry(feed, entry, subscriptions); - } - }.run(); + boolean inserted = UnitOfWork.run(sessionFactory, () -> feedUpdateService.addEntry(feed, entry, subscriptions)); if (inserted) { entryInserted.mark(); } diff --git a/src/main/java/com/commafeed/backend/service/DatabaseCleaningService.java b/src/main/java/com/commafeed/backend/service/DatabaseCleaningService.java index 73eb09c0..e5eb385d 100644 --- a/src/main/java/com/commafeed/backend/service/DatabaseCleaningService.java +++ b/src/main/java/com/commafeed/backend/service/DatabaseCleaningService.java @@ -17,8 +17,6 @@ import com.commafeed.backend.dao.FeedEntryDAO; import com.commafeed.backend.dao.FeedEntryDAO.FeedCapacity; import com.commafeed.backend.dao.FeedEntryStatusDAO; import com.commafeed.backend.dao.UnitOfWork; -import com.commafeed.backend.model.Feed; -import com.commafeed.backend.model.FeedEntryStatus; /** * Contains utility methods for cleaning the database @@ -42,13 +40,7 @@ public class DatabaseCleaningService { long total = 0; int deleted = 0; do { - deleted = new UnitOfWork(sessionFactory) { - @Override - protected Integer runInSession() throws Exception { - List feeds = feedDAO.findWithoutSubscriptions(1); - return feedDAO.delete(feeds); - }; - }.run(); + deleted = UnitOfWork.run(sessionFactory, () -> feedDAO.delete(feedDAO.findWithoutSubscriptions(1))); total += deleted; log.info("removed {} feeds without subscriptions", total); } while (deleted != 0); @@ -61,12 +53,7 @@ public class DatabaseCleaningService { long total = 0; int deleted = 0; do { - deleted = new UnitOfWork(sessionFactory) { - @Override - protected Integer runInSession() throws Exception { - return feedEntryContentDAO.deleteWithoutEntries(BATCH_SIZE); - } - }.run(); + deleted = UnitOfWork.run(sessionFactory, () -> feedEntryContentDAO.deleteWithoutEntries(BATCH_SIZE)); total += deleted; log.info("removed {} contents without entries", total); } while (deleted != 0); @@ -77,13 +64,8 @@ public class DatabaseCleaningService { public long cleanEntriesForFeedsExceedingCapacity(final int maxFeedCapacity) { long total = 0; while (true) { - List feeds = new UnitOfWork>(sessionFactory) { - @Override - protected List runInSession() throws Exception { - return feedEntryDAO.findFeedsExceedingCapacity(maxFeedCapacity, BATCH_SIZE); - } - }.run(); - + List feeds = UnitOfWork.run(sessionFactory, + () -> feedEntryDAO.findFeedsExceedingCapacity(maxFeedCapacity, BATCH_SIZE)); if (feeds.isEmpty()) { break; } @@ -92,12 +74,8 @@ public class DatabaseCleaningService { long remaining = feed.getCapacity() - maxFeedCapacity; do { final long rem = remaining; - int deleted = new UnitOfWork(sessionFactory) { - @Override - protected Integer runInSession() throws Exception { - return feedEntryDAO.deleteOldEntries(feed.getId(), Math.min(BATCH_SIZE, rem)); - }; - }.run(); + int deleted = UnitOfWork.run(sessionFactory, + () -> feedEntryDAO.deleteOldEntries(feed.getId(), Math.min(BATCH_SIZE, rem))); total += deleted; remaining -= deleted; log.info("removed {} entries for feeds exceeding capacity", total); @@ -113,13 +91,8 @@ public class DatabaseCleaningService { long total = 0; int deleted = 0; do { - deleted = new UnitOfWork(sessionFactory) { - @Override - protected Integer runInSession() throws Exception { - List list = feedEntryStatusDAO.getOldStatuses(olderThan, BATCH_SIZE); - return feedEntryStatusDAO.delete(list); - } - }.run(); + deleted = UnitOfWork.run(sessionFactory, + () -> feedEntryStatusDAO.delete(feedEntryStatusDAO.getOldStatuses(olderThan, BATCH_SIZE))); total += deleted; log.info("cleaned {} old read statuses", total); } while (deleted != 0); diff --git a/src/main/java/com/commafeed/backend/service/StartupService.java b/src/main/java/com/commafeed/backend/service/StartupService.java index 51734ccf..4c914818 100644 --- a/src/main/java/com/commafeed/backend/service/StartupService.java +++ b/src/main/java/com/commafeed/backend/service/StartupService.java @@ -44,15 +44,10 @@ public class StartupService implements Managed { @Override public void start() throws Exception { updateSchema(); - new UnitOfWork(sessionFactory) { - @Override - protected Void runInSession() throws Exception { - if (userDAO.count() == 0) { - initialData(); - } - return null; - } - }.run(); + long count = UnitOfWork.run(sessionFactory, () -> userDAO.count()); + if (count == 0) { + UnitOfWork.run(sessionFactory, () -> initialData()); + } } private void updateSchema() { diff --git a/src/main/java/com/commafeed/frontend/servlet/CustomCssServlet.java b/src/main/java/com/commafeed/frontend/servlet/CustomCssServlet.java index 7d487548..a0c1d355 100644 --- a/src/main/java/com/commafeed/frontend/servlet/CustomCssServlet.java +++ b/src/main/java/com/commafeed/frontend/servlet/CustomCssServlet.java @@ -32,23 +32,12 @@ public class CustomCssServlet extends HttpServlet { protected void doGet(final HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/css"); - final Optional user = new UnitOfWork>(sessionFactory) { - @Override - protected Optional runInSession() throws Exception { - return new SessionHelper(req).getLoggedInUser(); - } - }.run(); + final Optional user = UnitOfWork.run(sessionFactory, () -> new SessionHelper(req).getLoggedInUser()); if (!user.isPresent()) { return; } - UserSettings settings = new UnitOfWork(sessionFactory) { - @Override - protected UserSettings runInSession() { - return userSettingsDAO.findByUser(user.get()); - } - }.run(); - + UserSettings settings = UnitOfWork.run(sessionFactory, () -> userSettingsDAO.findByUser(user.get())); if (settings == null || settings.getCustomCss() == null) { return; } diff --git a/src/main/java/com/commafeed/frontend/servlet/NextUnreadServlet.java b/src/main/java/com/commafeed/frontend/servlet/NextUnreadServlet.java index a2c3f29f..cbfd64c8 100644 --- a/src/main/java/com/commafeed/frontend/servlet/NextUnreadServlet.java +++ b/src/main/java/com/commafeed/frontend/servlet/NextUnreadServlet.java @@ -51,17 +51,11 @@ public class NextUnreadServlet extends HttpServlet { final String categoryId = req.getParameter(PARAM_CATEGORYID); String orderParam = req.getParameter(PARAM_READINGORDER); - final Optional user = new UnitOfWork>(sessionFactory) { - @Override - protected Optional runInSession() throws Exception { - SessionHelper sessionHelper = new SessionHelper(req); - Optional loggedInUser = sessionHelper.getLoggedInUser(); - if (loggedInUser.isPresent()) { - userService.performPostLoginActivities(loggedInUser.get()); - } - return loggedInUser; - } - }.run(); + SessionHelper sessionHelper = new SessionHelper(req); + Optional user = sessionHelper.getLoggedInUser(); + if (user.isPresent()) { + UnitOfWork.run(sessionFactory, () -> userService.performPostLoginActivities(user.get())); + } if (!user.isPresent()) { resp.sendRedirect(resp.encodeRedirectURL(config.getApplicationSettings().getPublicUrl())); return; @@ -69,32 +63,31 @@ public class NextUnreadServlet extends HttpServlet { final ReadingOrder order = StringUtils.equals(orderParam, "asc") ? ReadingOrder.asc : ReadingOrder.desc; - FeedEntryStatus status = new UnitOfWork(sessionFactory) { - @Override - protected FeedEntryStatus runInSession() throws Exception { - FeedEntryStatus status = null; - if (StringUtils.isBlank(categoryId) || CategoryREST.ALL.equals(categoryId)) { - List subs = feedSubscriptionDAO.findAll(user.get()); - List statuses = feedEntryStatusDAO.findBySubscriptions(user.get(), subs, true, null, null, 0, 1, - order, true, false, null); - status = Iterables.getFirst(statuses, null); - } else { - FeedCategory category = feedCategoryDAO.findById(user.get(), Long.valueOf(categoryId)); - if (category != null) { - List children = feedCategoryDAO.findAllChildrenCategories(user.get(), category); - List subscriptions = feedSubscriptionDAO.findByCategories(user.get(), children); - List statuses = feedEntryStatusDAO.findBySubscriptions(user.get(), subscriptions, true, null, - null, 0, 1, order, true, false, null); - status = Iterables.getFirst(statuses, null); + FeedEntryStatus status = UnitOfWork.run( + sessionFactory, + () -> { + FeedEntryStatus s = null; + if (StringUtils.isBlank(categoryId) || CategoryREST.ALL.equals(categoryId)) { + List subs = feedSubscriptionDAO.findAll(user.get()); + List statuses = feedEntryStatusDAO.findBySubscriptions(user.get(), subs, true, null, null, 0, 1, + order, true, false, null); + s = Iterables.getFirst(statuses, null); + } else { + FeedCategory category = feedCategoryDAO.findById(user.get(), Long.valueOf(categoryId)); + if (category != null) { + List children = feedCategoryDAO.findAllChildrenCategories(user.get(), category); + List subscriptions = feedSubscriptionDAO.findByCategories(user.get(), children); + List statuses = feedEntryStatusDAO.findBySubscriptions(user.get(), subscriptions, true, null, + null, 0, 1, order, true, false, null); + s = Iterables.getFirst(statuses, null); + } } - } - if (status != null) { - status.setRead(true); - feedEntryStatusDAO.saveOrUpdate(status); - } - return status; - } - }.run(); + if (s != null) { + s.setRead(true); + feedEntryStatusDAO.saveOrUpdate(s); + } + return s; + }); if (status == null) { resp.sendRedirect(resp.encodeRedirectURL(config.getApplicationSettings().getPublicUrl())); @@ -103,5 +96,4 @@ public class NextUnreadServlet extends HttpServlet { resp.sendRedirect(resp.encodeRedirectURL(url)); } } - }