0 Replies Latest reply on May 16, 2016 1:09 PM by dkelkhoff

    How to configure data-sources, persistence-units, and EntityManager for per-client database architecture

    dkelkhoff

      In our infrastructure, each of our clients have a their own copy of our primary application database. Thus far, we have configured this setup in jboss by having an entry for each of those databases as a separate data-source in standalone.xml, and for each of them, a separate persistence-unit in persistence.xml.

       

      We then have a class we call EntityManagerResourceInterface, in which we define an EntityManager for each of the different persistence units, and it has a method to return the appropriate one to other EJBs based on the client of the current request, as roughly shown here:

       

      ...

      @PersistenceContext(unitName = "client_2")

      private EntityManager client2EntityManager;

      ...

       

      public EntityManager getEntityManager() {

         ...

         else if(clientId == 2) {

            return (client2EntityManager);

         }

         ...

      }

       

      ...

      @Produces
      @EntityManagerQualifier("client_2")

      public EntityManager getClient2EntityManager() {

         return (client2EntityManager);

      }

      ...

       

      This has worked fine while we've had less than 15 clients, and we could hard-code all of their databases into standalone.xml, persistence.xml, and our EntityManagerResource class, and have every jboss server connect to all of those databases, etc.  However, we are now scaling to the point where this is no longer working for us (both from the perspective of maintaining these files, and from having this many resources consumed in each jboss server).

       

      So, what we would like to do would be to only have 1 entry in standalone.xml and persistence.xml for all of these per-client databases, and since we are already always accessing EntityManager instances through our EntityManagerResource class, we want to somehow make it point the EntityManager instance at the correct database before it returns the EntityManager to a caller.  This way, whether a particular jboss server is serving a single client, or many clients, and whatever client ids are being serviced, they can all work with the same jboss configuration.  And, that way, each jboss server will only be connected to, and consuming resources for, the clients that it is serving. 


      We have attempted to use Persistence.createEntityManagerFactory(), passing a property map including "hibernate.default_schema" set to point at the appropriate client-specific database, and this has worked for read-only operations, but we're apparently not correctly re-using the EntityManagers (i.e., every time we try to modify or delete an entity, we're told it's not managed).  I can post some of that code if needed, but I kinda feel like we went the wrong way with it...

       

      Please let us know if there is a "standard" way to configure a setup like this in JBoss, and if so, how to go about it.

       

      Thanks!