On Feb 17, 2009, at 7:44 AM, <thomas.th.hamac...@partner.bmw.ch> <thomas.th.hamac...@partner.bmw.ch
> wrote:
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.
There's no convenient way to get the hashcode.
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?
That's really the big question. I'm not exactly sure how your tests
are written, but it would be fine to use them both as long as it was
understood they are two completely different Persistence Contexts
(i.e. caches). This is pretty much how things will look at runtime
anyway -- i.e. multiple threads and transactions each with it's own
persistence context. If you don't attempt to use them together in the
same transaction and you don't attempt to create two transactions in
the same thread simultaneously, it should be fine.
The bigger thing will be to respect the mode in which the persistence
unit in question is meant to work. If it is a RESOURCE_LOCAL unit,
you'll want to use the EntityTransaction API to transactionally demark
you work with the created EntityManager. If it is a JTA (the default)
persistence unit, you'll want begin/commit transactions via either a
UserTransaction or the TransactionManager directly when you work with
the EntityManager.
-David
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