I am having a hard time not to repeat myself in a Java program I am working on at the moment.
Say, I need to declare a lot of methods that basically are structured in the following way:
public SomeEntity doSomething (String someAttribute, String anotherAttribute) { EntityManager em = this.createEntityManager(); EntityTransaction tx = null; try { /* * ... independent logic ... */ tx = em.getTransaction(); } catch (RuntimeException e) { if (tx != null && tx.isActive()) { tx.rollback(); } throw e; } finally { em.close(); } return something; }
The method body of all methods needs to contain theses elements for resource management.
The "independent logic" itself will be rather complex too, so putting the try/catch statement in a separate method won't really work.
I want to avoid to repeat this code. What are the best practices to apply in these situations?
Exponentially because if each method branches in two different ways then every time you call another method you're squaring the previous number of potential outcomes. By the time you've called five methods you are up to 256 possible outcomes at a minimum.
To avoid writing multiple try catch async await in a function, a better option is to create a function to wrap each try catch. The first result of the promise returns an array where the first element is the data and the second element is an error. And if there's an error, then the data is null and the error is defined.
Yes, It is possible to have a try block without a catch block by using a final block. As we know, a final block will always execute even there is an exception occurred in a try block, except System.
Only error prone code is within the try block and the handling of that error is written in the catch block. It is used to handle run time exceptions. It is a good practice to write the code in try block which may generate an error , so, that the code doesn't terminate abruptly.
Create an interface:
public interface EntityManagerAction { public void execute(EntityManager em); }
And a utility class:
public class EntityUtil { public static void executeWithEntityManager(EntityManagerAction action) { EntityManager em = someHowCreateEntityManager(); EntityTransaction tx = null; try { action.execute(em); tx = em.getTransaction(); } catch (RuntimeException e) { if (tx != null && tx.isActive()) { tx.rollback(); } throw e; } finally { em.close(); } } }
Now you can re-use the boiler-plate in the EntityUtil class, and your code becomes:
public SomeEntity doSomething (String someAttribute, String anotherAttribute) { Something something; EntityUtil.executeWithEntityManager(new EntityManagerAction() { public void execute(EntityManager em ) { /* * ... independent logic ... */ //use the passed in 'em' here. } }); return something; }
See also What is the "Execute Around" idiom?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With