JPA Inheritance and EJB Polymorphism

I have a Java EE 6 web application using container-managed transactions, and Context saving container via

@PersistenceContext private EntityManager em; 

In the JPA layer, I have an inheritance strategy where MyExtendedClassA and MyEntendedClassB extend abstract MyClass .

I use stateless facade service classes to implement data access using the find , findAll , merge , persist , remove methods:

 @Stateless public class MyExtendedClassAFacade { @PersistenceContext private EntityManager em; public void persist(MyExtendedClassA a) { // ... } // other methods } 

So far so good. Now I have to implement polymorphism regarding the behavior of extended classes. This behavior is to control some other objects in the database, so this requires a PersistenceContext (and therefore I need to use other stateless EJBs):

 @Stateful public class MyBean { @EJB private MyClassFacade myClassFacade; // stateless facade service class public void doSomething() { for (MyClass c : myClassFacade.findAll()) { // here I need to perform operations on the db. // The implementation differs on each extended class. // I want to avoid a brute-force coding like: if (c.getClass().equals(MyExtendedClassA.class)) { @EJB MyExtendedClassAFacade myClassFacadeA; myClassFacadeA.doSomething((MyExtendedClassA) c); } else if (c.getClass().equals(MyExtendedClassB.class)) @EJB MyExtendedClassBFacade myClassFacadeB; myClassFacadeB.doSomething((MyExtendedClassB) c); } // Instead, I would like to write something like: @EJB AnotherStatelessBean asb; asb.doSomething(c); } } } 

Is there any abstraction pattern that I can use for this purpose?

+2
source share
1 answer

This is an EJB polymorphism and can be applied to other situations. This does not apply directly to JPA inheritance.

The trick is to use the @Local interface for EJB:

 @Local public interface MyClassFacadeInterface { public void doSomething(MyClass c); } 

and let the existing Facade Stateless beans for extended classes implement this interface.

After that, Facade stateless implementation classes should be searched with InitialContext.lookup("java:module/MyExtendedClassAFacade") . The trick here is to provide facade class names associated with entity classes to facilitate the search. Code to be used at the business level:

 public void doSomething() { for (MyClass c : myClassFacade.findAll()) { String lookupName = getNameFromClassName(c.getClass().name()); MyClassFacadeInterface myInt = (MyClassFacadeInterface) new InitialContex().lookup(lookupName); myInt.doSomething(c); } } 
+3
source

Source: https://habr.com/ru/post/1437296/


All Articles