Details

    • Type: New Feature New Feature
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Labels:
      None

      Description

      Without changing code and redeploying my application, I need to be able to switch persistence units in some of my EJBs based on client connected to system.
      It is similar to multitenancy, but whereas there a single DB is divided into equal shares and shared between multiple tenants, here a single tenant wants multiple DBs appearing as a single one.
      During runtime based on the client connected to the EJB, the specific database should be selected.
      Currently I achieve this using JDBC connections and just changing the database connection details based on client connected.
      The database connection details are stored in the main system database and retrieved when the client connects.
      This allows the system to grow with ease as new client databases can be created on the fly and simply linked to the client
      in the database.
      Ideally I would like to dynamically add new persistence units to the system (persistence.xml) and then in my database
      link these persistence units to a given client. When the client connects, the system loads the required persistence unit.

        Activity

        Hide
        ldemichiel added a comment -

        I think you are really asking for multitenancy support in Java EE, which is something that we don't yet support. This is a candidate item for Java EE 8, at which point we should revisit this issue for JPA.

        Show
        ldemichiel added a comment - I think you are really asking for multitenancy support in Java EE, which is something that we don't yet support. This is a candidate item for Java EE 8, at which point we should revisit this issue for JPA.
        Hide
        c.beikov added a comment -

        This would be something really nice to have but I also think that this is already possible.
        You coud have e.g. a CDI producer for the EntityManager which returns a proxy that is actually capable of that switching.
        This is really nice, I think I will implement this in my application too

        public class EnvironmentAwareEntityManager implements EntityManager {
        
          @Inject
          @Any
          private Instance<EntityManager> ems;
        
          private EntityManager select(){
            for(EntityManager em : ems) {
              if(!(em instanceof EnvironmentAwareEntityManager)) {
                // Do your selection based on your needs
              }
            }
          }
        
          // ... delegate all calls to the result of select()
        }
        
        Show
        c.beikov added a comment - This would be something really nice to have but I also think that this is already possible. You coud have e.g. a CDI producer for the EntityManager which returns a proxy that is actually capable of that switching. This is really nice, I think I will implement this in my application too public class EnvironmentAwareEntityManager implements EntityManager { @Inject @Any private Instance<EntityManager> ems; private EntityManager select(){ for (EntityManager em : ems) { if (!(em instanceof EnvironmentAwareEntityManager)) { // Do your selection based on your needs } } } // ... delegate all calls to the result of select() }
        Hide
        arjan tijms added a comment -

        @c.beikov

        With that method, how would you actually add a new persistence unit at runtime, or alternatively let an existing persistence unit point to a different database?

        Show
        arjan tijms added a comment - @c.beikov With that method, how would you actually add a new persistence unit at runtime, or alternatively let an existing persistence unit point to a different database?
        Hide
        c.beikov added a comment -

        Adding a new persistence unit is kind of tricky with the current state of the API. This is currently only possible my managing the EMFs within the application but you probably also have to depend on some code of the underlying persistence provider to do the dynamic configuration of the EMF. Transaction Management and so on could be handeled by using the new transaction interceptors of Java EE 7(at least I think that it would be possible, not sure about that). It is possible but not entirely with the standards provided by JPA.

        The requirement was to switch PUs but not the underlying datasource of a PU. So when you know at deployment time what PUs you have you can do it like that.

        I could still think of something else, but this is probably the worst solution. You could set a comment hint on every query you execute, let the address of the PUs database point to a proxy that does the selection by inspecting the comments.

        Show
        c.beikov added a comment - Adding a new persistence unit is kind of tricky with the current state of the API. This is currently only possible my managing the EMFs within the application but you probably also have to depend on some code of the underlying persistence provider to do the dynamic configuration of the EMF. Transaction Management and so on could be handeled by using the new transaction interceptors of Java EE 7(at least I think that it would be possible, not sure about that). It is possible but not entirely with the standards provided by JPA. The requirement was to switch PUs but not the underlying datasource of a PU. So when you know at deployment time what PUs you have you can do it like that. I could still think of something else, but this is probably the worst solution. You could set a comment hint on every query you execute, let the address of the PUs database point to a proxy that does the selection by inspecting the comments.
        Hide
        jbsmathers added a comment -

        This would allow the end user to make new db connections, and that would add a variety of functionalities not currently available in jee without redeployment. I have wondered about this since JEE5 and unless there are excellent reasons not to do it, I hope its in jee8.

        Show
        jbsmathers added a comment - This would allow the end user to make new db connections, and that would add a variety of functionalities not currently available in jee without redeployment. I have wondered about this since JEE5 and unless there are excellent reasons not to do it, I hope its in jee8.

          People

          • Assignee:
            ldemichiel
            Reporter:
            likenootherufo
          • Votes:
            7 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated: