tomee-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From <Thomas.TH.Hamac...@partner.bmw.ch>
Subject RE: Re: Obtaining EntityManager programatically for test purposes
Date Tue, 17 Feb 2009 15:44:59 GMT
David,



thanks a lot for your answer.

Do I have any chance to get the hashcode as well?

I could do the workaround to ignore the id and imply that the persistence-unit is unique,
but it would even be cleaner, if I would look for the exact jndi-name.

But as I do this programatically I currently never know the id exactly.



Just another question how to proceed further: I know I can create a new EntityManager from
the EntityManagerFactory, but is this the way I should go here?

Will this be the entityManager which is also injected into the other SessionBeans by openEJB
or will it be another one?

The reason I am asking is, that I also use an EntityManager in my Services, which I call within
my tests. So wouldn´t it cause some troubles if I work with different EntityManagers?



Thanks a lot



Thomas











Hi Thomas,



We actually do have something similar internally, but the trick is that persistence unit names
are not required to be unique outside the persistence.xml file (i.e. it's legal to have multiple
persistence.xml files in various modules in your app all with the same name despite that they
are different persistence units). So currently we generate an id for the persistence.xml file
itself and tack that on to the end of the persistence unit name before registering it in JNDI.
The format is:

 "java:openejb/PersistenceUnit/" + unitName + " " + id



The id is a hashCode we generate to identify the exact persistence.xml file.

This is more for our purposes internally, but it is possible to get a list of them outside
an EJB or Servlet. Inside a Servlet or EJB you don't currently have access to java:openejb
though we plan to add that.

Here's a small example:

The persistence.xml file



<persistence xmlns="http://java.sun.com/xml/ns/persistence"<http://java.sun.com/xml/ns/persistence%22>;
version="1.0">

    <persistence-unit name="orange-unit">
      <jta-data-source>Orange</jta-data-source>
      <non-jta-data-source>OrangeUnmanagedamanged</non-jta-data-source>
    </persistence-unit>
    <persistence-unit name="lime-unit">
      <jta-data-source>Lime</jta-data-source>
      <non-jta-data-source>LimeUnmanagedamanged</non-jta-data-source>
    </persistence-unit>
  </persistence>

If you executed code like this in your test case:

    // Do not pass in LocalInitialContextFactory
    Context context = new InitialContext();

    context = (Context) context.lookup("java:openejb/PersistenceUnit");

    Map<String,Object> map = Debug.contextToMap(context);
    for (String key : map.keySet()) {
        System.out.println(key);
    }

You see this in the output:

   "lime-unit 3506402"
   "orange-unit 3506402"



Looking up these will give you the internal EntityManagerFactory we use to create the various
EntityManager instances at runtime (i.e. transaction start for TRANSACTION scope or stateful
session bean creation for EXTENDED scope).

Note the "Debug.contextToMap" call is just you standard iterate over JNDI code. Here it is
if you want it:

public static Map<String,Object> contextToMap(Context context) throws NamingException
{ Map<String, Object> map = new TreeMap<String, Object>(String.CASE_INSENSITIVE_ORDER);

        contextToMap(context, "", map);
        return map;
    }



public static void contextToMap(Context context, String baseName, Map<String,Object>
results) throws NamingException { NamingEnumeration<Binding> namingEnumeration = context.listBindings("");

        while (namingEnumeration.hasMoreElements()) {
            Binding binding = namingEnumeration.nextElement();
            String name = binding.getName();
            String fullName = baseName + name;
            Object object = binding.getObject();
            results.put(fullName, object);
            if (object instanceof Context) {


contextToMap((Context) object, fullName + "/", results);

            }
        }
    }



Further note to future readers who might want to iterate over the entire java:openejb tree.
Caution should be used with the java:openejb/ejb/, java:openejb/Deployment/, and java:openejb/client/
sections of the tree as they will contain any Stateful session bean's you have in your platform
and calling "binding.getObject()" on those will cause stateful session bean instances to be
created.

In terms of future functionality, we would like to provide an alternate JNDI view of the persistence
units that doesn't involve the unique ID and simply is "unit name".

-David





Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message