glassfish
  1. glassfish
  2. GLASSFISH-1575

Create more than one EntityManagerFactory for the same PersistenceUnit

    Details

    • Type: New Feature New Feature
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 9.1pe
    • Fix Version/s: not determined
    • Component/s: entity-persistence
    • Labels:
      None
    • Environment:

      Operating System: All
      Platform: All

    • Issuezilla Id:
      1,575

      Description

      Hi,

      when I try to create more than one EntityManagerFactory for the same
      PesistenceUnit (to use different user/passwords for login) I run into the
      problem that toplink only creates only one EntityManagerFactory and returns it
      via Persistence.createEntityManagerFactory(..) even if I use a different
      properties object.

      I use the following code:

      Map<String, String> connectProps1 = new HashMap<String, String>();
      connectProps1.put(TopLinkProperties.JDBC_USER, "user1");
      connectProps1.put(TopLinkProperties.JDBC_PASSWORD,"password1");

      EntityManagerFactory myemf1 = Persistence.createEntityManagerFactory("default",
      connectProps1);

      EntityManager em1 = myemf1.createEntityManager();

      List userstring1 = em1.createNativeQuery("select user from dual").getResultList
      ();
      String usi1 = userstring1.toString();
      System.out.println(usi1);

      Map<String, String> connectProps2 = new HashMap<String, String>();
      connectProps2.put(TopLinkProperties.JDBC_USER, "user2");
      connectProps2.put(TopLinkProperties.JDBC_PASSWORD,"password2");

      EntityManagerFactory myemf2 = Persistence.createEntityManagerFactory("default",
      connectProps2);

      EntityManager em2 = myemf2.createEntityManager();

      List userstring2 = em2.createNativeQuery("select user from dual").getResultList
      ();
      String usi2 = userstring2.toString();
      System.out.println(usi2);

      But Toplink essentials does only creates one EntityManagerFactory (when
      executing myemf1.createEntityManager() I think ) and starts the database
      connections, but the second Persistence.createEntityManagerFactory("default",
      connectProps2) call seems to be ignored.
      The result from "select user from dual" is in both cases "user1"

      By the way:
      It seems that Hibernate can create more than one EntityManagerFactory per
      PesistenceUnit.

      Best regards and thanks for any feedback,
      Alex Schaefer

        Activity

        Hide
        tware added a comment -

        Related to issue 1576. Implementing one of these two Features should provide
        most of the functionality.

        Changing to "Feature"

        Show
        tware added a comment - Related to issue 1576. Implementing one of these two Features should provide most of the functionality. Changing to "Feature"
        Hide
        marina vatkina added a comment -

        resetting the default owner

        Show
        marina vatkina added a comment - resetting the default owner
        Hide
        franos13 added a comment -

        That seems to be possible with Hibernate.
        So why TopLink couldn't do the same !

        Show
        franos13 added a comment - That seems to be possible with Hibernate. So why TopLink couldn't do the same !
        Hide
        tware added a comment -

        The fact that another provider has chosen to implement this functionality does
        not make it a bug in TopLink Essentials. Resetting to Feature.

        This is definitely a desirable feature.

        Show
        tware added a comment - The fact that another provider has chosen to implement this functionality does not make it a bug in TopLink Essentials. Resetting to Feature. This is definitely a desirable feature.
        Hide
        antodasana added a comment -

        Hello.

        Just in case you find interesting my comments:

        I am currently developing JPA in J2SE and this issue is the reason I can not use
        TopLink Essentials. I have a 'logon' screen with connections to different
        databases and once I open a connection by creating an 'em factory', no matter
        the properties 'map' I send to 'Persistence' this will always return the same
        'em factory', and this makes TopLink unusable in my case.

        Maybe this is a bug in the specification: what makes sense is having different
        connections for different connection properties, once multiple factories are
        permitted by the specification (see comments bellow).

        TopLink Essentials was my initial choice but because of this issue I found
        myself forced to move to OpenJPA. I guess my case is far from being the only one.

        Thanks for your time and regards.
        Antonio Sánchez.

        --------------

        From: JSR 220: Enterprise JavaBeansTM,Version 3.0 - Java Persistence API - Final
        Release - Pg. 115. 5.3 Obtaining an Entity Manager Factory.

        "More than one entity manager factory instance may be available simultaneously
        in the JVM.[35]

        [35] This may be the case when using multiple databases, since in a typical
        configuration a single entity manager only communicates with a single database.
        There is only one entity manager factory per persistence unit, however."

        Show
        antodasana added a comment - Hello. Just in case you find interesting my comments: I am currently developing JPA in J2SE and this issue is the reason I can not use TopLink Essentials. I have a 'logon' screen with connections to different databases and once I open a connection by creating an 'em factory', no matter the properties 'map' I send to 'Persistence' this will always return the same 'em factory', and this makes TopLink unusable in my case. Maybe this is a bug in the specification: what makes sense is having different connections for different connection properties, once multiple factories are permitted by the specification (see comments bellow). TopLink Essentials was my initial choice but because of this issue I found myself forced to move to OpenJPA. I guess my case is far from being the only one. Thanks for your time and regards. Antonio Sánchez. -------------- From: JSR 220: Enterprise JavaBeansTM,Version 3.0 - Java Persistence API - Final Release - Pg. 115. 5.3 Obtaining an Entity Manager Factory. "More than one entity manager factory instance may be available simultaneously in the JVM. [35] [35] This may be the case when using multiple databases, since in a typical configuration a single entity manager only communicates with a single database. There is only one entity manager factory per persistence unit, however."
        Hide
        ailitche added a comment -

        There is a workaround in Eclipselink 1.0 (Eclipselink is a new persistence
        provider for GF, it's a superset of TopLink Essentials
        http://www.eclipse.org/eclipselink/downloads/)

        Eclipselink still doesn't allow multiple EntityManagerFactories corresponding
        to the same persistence unit and using different connection string, but it
        allows creating EntityManagers with individual connection strings (as long as
        the database platform is the same: can't connect on em to Oracle, another to
        Sybase).
        EntityManagerFactory must be configured to use exclusive isolated connection
        for each EntityManager.

        Map<String, String> connectProps1 = new HashMap<String, String>();
        connectProps1.put(PersistenceUnitProperties.JDBC_USER, "user1");
        connectProps1.put(PersistenceUnitProperties.JDBC_PASSWORD,"password1");
        // shared cache should not be used - each em has its own cache.
        connectProps1.put(PersistenceUnitProperties.CACHE_SHARED_DEFAULT,"false");
        // exclusive connection should be used by each em.
        connectProps1.put
        (PersistenceUnitProperties.EXCLUSIVE_CONNECTION_MODE,ExclusiveConnectionMode.Iso
        lated);

        EntityManagerFactory myemf1 = Persistence.createEntityManagerFactory("default",
        connectProps1);

        // uses connection properties specified in the factory.
        EntityManager em1 = myemf1.createEntityManager();

        Map<String, String> connectProps2 = new HashMap<String, String>();
        connectProps2.put(PersistenceUnitProperties.JDBC_USER, "user2");
        connectProps2.put(PersistenceUnitProperties.JDBC_PASSWORD,"password2");

        EntityManager em2 = myemf1.createEntityManager(connectProps2);

        Note that because each EntityManager uses its own exclusive connection it must
        be explicitly closed when no longer needed to avoid connection leakage.

        Show
        ailitche added a comment - There is a workaround in Eclipselink 1.0 (Eclipselink is a new persistence provider for GF, it's a superset of TopLink Essentials http://www.eclipse.org/eclipselink/downloads/ ) Eclipselink still doesn't allow multiple EntityManagerFactories corresponding to the same persistence unit and using different connection string, but it allows creating EntityManagers with individual connection strings (as long as the database platform is the same: can't connect on em to Oracle, another to Sybase). EntityManagerFactory must be configured to use exclusive isolated connection for each EntityManager. Map<String, String> connectProps1 = new HashMap<String, String>(); connectProps1.put(PersistenceUnitProperties.JDBC_USER, "user1"); connectProps1.put(PersistenceUnitProperties.JDBC_PASSWORD,"password1"); // shared cache should not be used - each em has its own cache. connectProps1.put(PersistenceUnitProperties.CACHE_SHARED_DEFAULT,"false"); // exclusive connection should be used by each em. connectProps1.put (PersistenceUnitProperties.EXCLUSIVE_CONNECTION_MODE,ExclusiveConnectionMode.Iso lated); EntityManagerFactory myemf1 = Persistence.createEntityManagerFactory("default", connectProps1); // uses connection properties specified in the factory. EntityManager em1 = myemf1.createEntityManager(); Map<String, String> connectProps2 = new HashMap<String, String>(); connectProps2.put(PersistenceUnitProperties.JDBC_USER, "user2"); connectProps2.put(PersistenceUnitProperties.JDBC_PASSWORD,"password2"); EntityManager em2 = myemf1.createEntityManager(connectProps2); Note that because each EntityManager uses its own exclusive connection it must be explicitly closed when no longer needed to avoid connection leakage.
        Hide
        Tom Mueller added a comment -

        Bulk change to set fix version to "not determined" where the issue is open but the value is for a released version.

        Show
        Tom Mueller added a comment - Bulk change to set fix version to "not determined" where the issue is open but the value is for a released version.

          People

          • Assignee:
            tware
            Reporter:
            alexs12345678
          • Votes:
            2 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated: