binding multiple entity manager with Guice, Guice-persist

2,472 views
Skip to first unread message

Josh Kamau

unread,
Nov 1, 2010, 5:20:36 AM11/1/10
to google...@googlegroups.com
HI team,

Kindly tell me , how do i bind multiple persistence contexts so that i can be able to create multiple entity managers with guice-persist.

I normally do this to bind a persistence context :  bindConstant().annotatedWith(JpaUnit.class).to("myPU");


regards.
Josh

bklough

unread,
Apr 26, 2011, 6:17:58 PM4/26/11
to google...@googlegroups.com
I notice there's no "multiModule" test in the source tree for the 3.0RC I have, so here's my quick stab at it:
  1. Create an Annotation for each of your persistence units (say DbOnePU.java, DbTwoPU.java).
  2. Define both "DbOne" and "DbTwo" persistence units in persistence.xml.
  3. Create DbOneManager & DbTwoManager (DAO or whatever that provides db access methods).
  4. Create DbOneInitializer & DbTwoInitializer (PersistService start/stop).
  5. For each persistence unit, create a PrivateModule following this pattern:
public class DbOneModule extends PrivateModule {
   protected void configure() {
       JpaPersistModule jpm = new JpaPersistModule("DbOne");
       jpm.properties(new Properties());       // some kinda bug without this
       jmp.addFinder(DbOneFinders.class); // an interface with any @Finder methods.
       install(jmp);
 
       bind(DbOneManager.class).annotatedWith(DbOnePU.class).to(DbOneManager.class);
       expose(DbOneManager.class).annotatedWith(DbOnePU.class);
 
       bind(DbOneInitializer.class).annotatedWith(DbOnePU.class).to(DbOneInitializer.class);
       expose(DbOneInitializer.class).annotatedWith(DbOnePU.class);
   }
}
 
Injector creation, at least:
injector = Guice.createInjector(new DbOneModule(), new DbTwoModule());
 
Injection usage would be:
 
@Inject @DbOnePU DbOneManager dbOneMgr;
@Inject @DbOnePU DbOneInitializer dbOneInit;
 
@Inject @DbTwoPU DbTwoManager dbTwoMgr;
@Inject @DbTwoPU DbTwoInitializer dbTwoInit;
 
Caveat:
With Hibernate 3.5, at least, both of my persistence units seem to find all of my Entities.  Should be able to isolate Entities to one persistence unit or the other, but no quick answer there.  Cheers! 
 
 

Alice

unread,
Jun 4, 2011, 10:51:00 AM6/4/11
to google...@googlegroups.com

Hi, Sir,

Thanks for providing this useful information. I have the multiple jar files that are categorized by the business modules. Each jar file contains a persistence.xml, the Entity beans, and the DAO classes. We have a logic domain DAO that needs to use DAOs defined in different jar files to retrieve the data from the same database.

Here is my pseudo code of the classes that are included in one of the jar files,

 

// JPA Entity that is created from a DB Customer table

@Entity

Public class Customer

{

}

 

// DAO that provides the method to access db table via Customer entity

Public class CustomerDao

{

               EntityManager entityManager;

               ….

}

 

// service initializer

public class CustomerDaoInitializer {

               @Inject

               CustomerDaoInitializer(PersistService service)

               {

                              service.start();

               }

}

 

I am trying to follow the steps you have given to create the persist module as shown below, but I don’t know how to define the annotation class for my persistence unit.

public class CustomerDaoModule extends PrivateModule

{

                 @Override

                 protected void configure()

                 {

                     install(new JpaPersistModule("rvng-customer"));

                     bind(CustomerDao.class).annotatedWith(??.class).to(CustomerDao.class);

                     expose(CustomerDao.class).annotatedWith(??.class);

                

                      bind(CustomerDaoInitialize.class).annotatedWith(??.class).to(CustomerDaoInitialize.class);

                      expose(CustomerDaoInitialize.class).annotatedWith(??.class);

      }

       

}

 

Could you please tell me how do you define your DbOnePU.java?  Any information is really appreciated.

Thanks for the help,

Alice

bklough

unread,
Jun 5, 2011, 1:12:11 PM6/5/11
to google...@googlegroups.com
Hi Alice.  Here's the template for the persistence unit binding annotation you're looking for.  For this discussion example, "JpaUnit" would be "DbOnePU", so DbOnePU.java.  Obviously, remove and/or modify the "default Defaults.DefaultUnit.class".

/**
 * <p>
 *  A guice binding annotation you should use to tell warp-persist the name of
 * the JPA persistence unit you wish to use. Bind a string with the name to this
 * annotation. For instance, if the name of your persistence unit is "myDb" you would
 * add the following in one of your guice modules:
 * </p>
 * <code>
 * bindConstant().annotatedWith(JpaUnit.class).to("myDb");
 * </code>
 * If you are using multiple JPA configurations in the same project (multiple modules),
 * bind to an instance of the JpaUnit annotation instead, specifying the module-level
 * binding annotation used to create the persistence module:
 * <code>
 * bindConstant().annotatedWith(JpaUnitInstance.of(MyDB.class)).to("myDb");
 * </code>
 * <p>
 *  You <b>must</b> bind a string to this annotation if using JPA. And it must match
 * a jpa unit named in your JPA persistence.xml.
 * </p>
 *
 * @author Dhanji R. Prasanna (dha...@gmail.com)
 * @since 1.0
 */
@BindingAnnotation
@Retention(RetentionPolicy.RUNTIME)
public @interface JpaUnit {
    Class<? extends Annotation> value() default Defaults.DefaultUnit.class;
}

Alice

unread,
Jun 7, 2011, 2:15:26 PM6/7/11
to google...@googlegroups.com
Hi, Sir, thanks for providing the details.
 
but I can't fix the following deploy error when deploying my servlet to JBoss 5.1
1) Unable to create binding for com.google.inject.persist.PersistService. It was already configured on one or more child injectors or private modules
    bound at com.google.inject.persist.jpa.JpaPersistModule.configurePersistence(JpaPersistModule.java:69)
  If it was in a PrivateModule, did you forget to expose the binding?
  while locating com.google.inject.persist.PersistService
    for parameter 1 at com.google.inject.persist.PersistFilter.<init>(PersistFilter.java:71)
  while locating com.google.inject.persist.PersistFilter
2) Unable to create binding for com.google.inject.persist.UnitOfWork. It was already configured on one or more child injectors or private modules
    bound at com.google.inject.persist.jpa.JpaPersistModule.configurePersistence(JpaPersistModule.java:70)
  If it was in a PrivateModule, did you forget to expose the binding?
  while locating com.google.inject.persist.UnitOfWork
    for parameter 0 at com.google.inject.persist.PersistFilter.<init>(PersistFilter.java:71)
  while locating com.google.inject.persist.PersistFilter
 
Here is are my annotation class for my persistence unit. since I use multiple persistence units, I also defined a  JpaUnitInstance class
 
@BindingAnnotation
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomerJpaUnit
{
}
 
class CustomerJpaUnitInstance<T extends Annotation> implements CustomerJpaUnit, Serializable
{     
     private static final long serialVersionUID = -1986769782077028259L;
     private final  Class<T> value;       
     private CustomerJpaUnitInstance(Class<T> annotation)
     {         
          this.value = annotation;     
     }       
 
     public Class<T> value()
     {         
          return this.value;     
     }       
 
        .....
}
 
 
here is my JPA module that extends PrivateModule:

public class CustomerDaoModule extends PrivateModule
{
      @Override
      protected void configure()
      {
            JpaPersistModule jpm = new JpaPersistModule("rvng-customer");

            jpm.properties(new Properties());       // some kinda bug without this
            install(jpm);
      
           bindConstant().annotatedWith(CustomerJpaUnitInstance.of(CustomerJpaUnit.class)).to("rvng-customer");
           bind(CustomerDao.class).annotatedWith(CustomerJpaUnit.class).to(CustomerDaoImpl.class);
           expose(CustomerDao.class).annotatedWith(CustomerJpaUnit.class);
     
           bind(CustomerDaoInitializer.class).annotatedWith(CustomerJpaUnit.class).to(CustomerDaoInitializer.class);
          expose(CustomerDaoInitializer.class).annotatedWith(CustomerJpaUnit.class);
      }
}
 
Similar, I have defined an annotation class and a private module with a different persistence unit. the pseudo code shown as below
public class RefereceDaoModule extends PrivateModule
{
       @Override
       protected void configure()
       {
           JpaPersistModule jpm = new JpaPersistModule("rvng-referece");

           jpm.properties(new Properties());       // some kinda bug without this
           install(jpm);
     
           bindConstant().annotatedWith( RefereceJpaUnitInstance.of( RefereceJpaUnit.class)).to("rvng-customer");
           bind( RefereceDao.class).annotatedWith( RefereceJpaUnit.class).to( RefereceDaoImpl.class);
           expose( RefereceDao.class).annotatedWith( RefereceJpaUnit.class);
     
           bind( RefereceDaoInitializer.class).annotatedWith( RefereceJpaUnit.class).to( RefereceDaoInitializer.class);
           expose( RefereceDaoInitializer.class).annotatedWith( RefereceJpaUnit.class);
      }
}

in my logic domain module, I invoke these two private modules:

public class CustomerDomainModule extends AbstractModule
{
      @Override
      protected void configure()
      {
            install(new ReferenceDaoModule());
  
            install(new CustomerDaoModule())
         ......
      }
}

In my test servlet, I  inject the CustomerDomainModule, like
 
public class GuiceServletConfig extends GuiceServletContextListener
{
       @Override
       protected Injector getInjector()
       {
              return Guice.createInjector(new ServletModule( )
              {
                   @Override
                   protected void configureServlets()
                  {
                           install(new CustomerDomainModule());
                           filter("/*").through(PersistFilter.class);
                           serve("/customerHandler").with(CustomerHandler.class);
                  }
               });
       }
}
 
Could you please advise what I did wrong? I really appreciate your help.
 
-Alice

bklough

unread,
Sep 17, 2011, 4:32:02 PM9/17/11
to google...@googlegroups.com
Sorry, Alice. Had to move onto other things before getting back to this.  Created a new topic to draw attention.  https://groups.google.com/d/topic/google-guice/2VK-bdsnjZc/discussion

Basically, remove any "filter("/*").through(PersistFilter.class);" statement(s)
you might have and this error will go away. Be aware, though, that your transactional method will change.

Reply all
Reply to author
Forward
0 new messages