in Education by

I created update() method which is using JPA. It looks like this: public boolean update(Programy program) throws Exception { try { entityManagerFactory = Persistence.createEntityManagerFactory("firebird_config_file"); entityManager = entityManagerFactory.createEntityManager(); entityManager.getTransaction().begin(); entityManager.merge(program); entityManager.getTransaction().commit(); entityManager.close(); entityManagerFactory.close(); return true; } catch (Exception e) { e.printStackTrace(); return false; } } In my save() and delete method I am changing only one thing - merge() -> persist() or delete(). Remaining part of code is similar as here. How can i refactor this code to simplify this? JavaScript questions and answers, JavaScript questions pdf, JavaScript question bank, JavaScript questions and answers pdf, mcq on JavaScript pdf, JavaScript questions and solutions, JavaScript mcq Test , Interview JavaScript questions, JavaScript Questions for Interview, JavaScript MCQ (Multiple Choice Questions)

Please log in or register to answer this question.

1 Answer

0 votes
by

This is a very good use-case for a pattern called template method. For example, you can create an abstract class, which wraps all your boilerplate code in perform method: abstract public class HibernateAction { private EntityManagerFactory entityManagerFactory; //I'm passing EntityManagerFactory, because it should be singleton and you shouldn't //probably create it from scratch everytime public HibernateAction(EntityManagerFactory entityManagerFactory) { this.entityManagerFactory = entityManagerFactory; } protected abstract T action(EntityManager entityManager, T entity); public boolean perform(T entity) throws Exception { try { var entityManager = entityManagerFactory.createEntityManager(); entityManager.getTransaction().begin(); action(entityManager, entity); //call to action which need to be overriden entityManager.getTransaction().commit(); entityManager.close(); return true; } catch (Exception e) { e.printStackTrace(); return false; } } } then you can just create a class which inherits HibernateAction: public class UpdateAction extends HibernateAction { public UpdateAction(EntityManagerFactory entityManagerFactory) { super(entityManagerFactory); } @Override protected Program action(EntityManager entityManager, Program entity) { return entityManager.merge(entity); } } and finally you can use it like this: public boolean update(Program program) throws Exception { return updateAction.perform(program); } But since anonymous methods are supported in Java (since Java 8), you could also rewrite it in a little bit less verbose way using higher order functions: public class HibernateAction2{ // no longer abstract private EntityManagerFactory entityManagerFactory; public HibernateAction2(EntityManagerFactory entityManagerFactory) { this.entityManagerFactory = entityManagerFactory; } //we expect a user to pass lambda function, which would tell us what to do with an entity manager public boolean perform (Consumer action) throws Exception { try { var entityManager = entityManagerFactory.createEntityManager(); entityManager.getTransaction().begin(); action.accept(entityManager); entityManager.getTransaction().commit(); entityManager.close(); return true; } catch (Exception e) { e.printStackTrace(); return false; } } } and then you can use it like: hibernateAction2.perform(em -> em.merge(program)); //for merge hibernateAction2.perform(em -> em.persist(program)); //for persist, etc. This is called loan pattern or loaner pattern (or bracket in FP languages), because you "loan" entity manager from hibernateAction2 to use it to do some kind of action, but it handles all other things, like creating an object or closing connection.

Related questions

...