9 Replies Latest reply on Oct 31, 2008 6:51 AM by skajotde

    Using EntityManager in a abstract super class

    mnrz

      Hello

      we have an interface say, DataAccessManipulator. since the method save(), delete() and update() are common for all the DAO classes we have created a GeneralDataAccessManipulator as an abstract class in which those methods have been implemented using EntityManager:

      public abstract class GeneralDataAccessManipulator implements DataAccessManipulator {
      
       @PersistenceContext
       private EntityManager entityManager;
      
       public void delete(Object entity) {
       if (!entityManager.contains(entity)) {
       entity = doMerge(entity);
       }
       try {
       doDelete(entity);
       } catch (Exception e) {
       e.printStackTrace();
       }
       //entityManager.flush();
       }
      
      //rest of the code...
      }
      


      now this class and many others are located in a jar file namely common-j2ee.jar

      because there are many project in the company that are developing at the same time we shared this recent jar file for all other projects.

      the problem is in our application we have to specify the unitName for the PersistenceContext and in another application this name may be different
      and because in the GeneralDataAccessManipulator we didn't specify unitName the app won't be deployed and of course if we set it, other apps will encounter the problem

      my question is if we can set that unitName in a way according to the applciation persistence unit.

      I've read something about @EJBS on class declaration but didn't understand it really. Can we make use of that?

      I am thinking of giving a specific unitName to the @PersistenceContext defined in abstract class an then inject the EM inside my app and set it as the name specified above in the SB I am using. Is this possible?



      thanks for your help


        • 1. Re: Using EntityManager in a abstract super class
          jaikiran

          I understand what you are trying to do here. There was a similar question sometime back on this forum http://www.jboss.com/index.html?module=bb&op=viewtopic&t=134276. See if using @Resource as mentioned in that thread is a feasible approach. That way, each application can have their own persistence unit name but bind them to this pre-decided JNDI name and inject it.

          • 2. Re: Using EntityManager in a abstract super class
            mnrz

             

            "jaikiran" wrote:
            I understand what you are trying to do here. There was a similar question sometime back on this forum http://www.jboss.com/index.html?module=bb&op=viewtopic&t=134276. See if using @Resource as mentioned in that thread is a feasible approach. That way, each application can have their own persistence unit name but bind them to this pre-decided JNDI name and inject it.



            Thanks Jaikiran, but what if we use say Glassfish instead of JBoss? this solution seems to be working on JBoss only. I know the designers don't accept this solution because they want the application to be portable

            • 3. Re: Using EntityManager in a abstract super class
              jaikiran

               

              "mnrz" wrote:


              Thanks Jaikiran, but what if we use say Glassfish instead of JBoss? this solution seems to be working on JBoss only. I know the designers don't accept this solution because they want the application to be portable


              You do have a valid point. But unfortunately, i don't see any other way of achieving this. I just found yet another question about this here http://www.jboss.com/index.html?module=bb&op=viewtopic&t=142514

              • 4. Re: Using EntityManager in a abstract super class
                alrubinger

                Check out the "persistence-unit-ref" facility defined by the javaee5.xsd. Then each of your applications becomes packaged with the appropriate descriptors.

                S,
                ALR

                • 5. Re: Using EntityManager in a abstract super class
                  skajotde

                  My team problem like this resolve with inheritance.

                  public abstract class GeneralDataAccessManipulator implements DataAccessManipulator {
                  
                   protected abstract EntityManager getEntityManager();
                  
                   public void delete(Object entity) {
                   if (!getEntityManager.contains(entity)) {
                   entity = doMerge(entity);
                   }
                   try {
                   doDelete(entity);
                   } catch (Exception e) {
                   e.printStackTrace();
                   }
                  }
                  
                  
                  public class Specjalization extedns GeneralDataAccessManipulator {
                  
                   @PersistenceContext(name="puXXX")
                   private EntityManager entityManager;
                  
                   protected EntityManager getEntityManager() {
                   return entityManager;
                   }
                  }


                  • 6. Re: Using EntityManager in a abstract super class
                    mnrz

                     

                    "skajotde" wrote:
                    My team problem like this resolve with inheritance.



                    Thanks Kamil
                    Actually we ended up with something like that. I've created a setter method for EntityManager and in @PostConstruct method I set the entity manager, however I don't like this sort of approaches but we had to :)

                    I think it's very useful if they provide an annotation for injections with local JNDi names


                    • 7. Re: Using EntityManager in a abstract super class
                      alrubinger

                       

                      "mnrz" wrote:
                      I think it's very useful if they provide an annotation for injections with local JNDi names


                      @Resource.mappedName ?

                      S,
                      ALR

                      • 8. Re: Using EntityManager in a abstract super class
                        mnrz

                         

                        "ALRubinger" wrote:

                        @Resource.mappedName ?

                        S,
                        ALR


                        Yes, I'm thinking of something like this:

                        
                        public abstract class GeneralDataAccessManipulator {
                        
                         @PersistenceContext(unitName = "common-unit")
                         EntityManager em;
                        }
                        
                        @Resource(mappedName = "common-unit", name="pu-cm", EntityManager.class)
                        public class AccountDataAccessManipulator extends GeneralDataAccessManipulator implements AccountDAO {
                        
                         //...
                        }
                        
                        


                        I've tested this but it didn't work.

                        • 9. Re: Using EntityManager in a abstract super class
                          skajotde

                           

                          "mnrz" wrote:
                          I don't like this sort of approaches but we had to :)

                          I think it's very useful if they provide an annotation for injections with local JNDi names


                          Why ? ;> It is point of inheritance. Write noninvasive generalization which model one aspect of system, and every class can specyfy to its needs. Contract is only EntityManager, not JNDI. I avoid Jndi if I can, in OO objects should have contract betwen themselves not between object and global register like JNDI.

                          You DAO even didnt have inherit GeneralDataAccessManipulator, may have:

                          @PersistenceContext(name="systemXPU")
                          private EntityManager entityManager;
                          property dataManipulatorSystemX = new GeneralDataAccessManipulator(enityiyManager);

                          Also I'm also pro named PU. Every @PersitenceContext should have name.