0

I'm working on a JavaEE application which uses JPA and is deployed on JBoss/Wildfly. I have my persistence.xml and standalone.xml properly configured for JPA to recognize the datasource. I understand that the normal way to obtain a context managed EntityManager is the following:

@PersistenceContext(unitName = "foo")
EntityManager em;

However, in my usecase the application defining the datasource and the library accessing it using JPA are separate. I need a way to programmatically produce an EntityManager by its persistence unit name. I understand that the easiest way to do this is this:

Persistence.createEntityManagerFactory("foo").createEntityManager()

However, this gives me an application managed entity manager, which forces me to handle transactions myself. I want to get a context managed entity manager, where I demarcate transactions by CDI-injecting UserTransaction or in similar ways. Is there a way to create an EntityManager at runtime and attach its transaction to the current context?

The original code worked around this by providing one global, application-scoped entitymanager. This way every occurance of EntityManager obviously has the same transaction. Besides other problems, this causes errors when trying to parallelize queries, as EntityManager is not thread safe. That's why I am currently trying to create entity manager instances ad-hoc, but keep the transaction semantics.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Felk
  • 7,720
  • 2
  • 35
  • 65
  • Could you please describe the use case in a little more detail? Why can't you simply configure the library with an injected `EntityManager`, in the bean that uses the library? If the library is CDI-enabled, why not use a `@Produces` method with a custom qualifier that the library will require? Finally, why not use `@PersistenceContext` without `unitName`? – crizzis Jan 08 '18 at 18:08
  • Using that generation of an EntityManager will create a new EntityManagerFactory for each EntityManager you need! and not close them either!!! –  Jan 08 '18 at 18:12
  • @crizzis The application using the library supposedly doesn't know about JPA, only about some persistence unit name, which happens to be implemented with JPA in one case. I need to supply a unitName, because I need to support multiple concurrent datasource. This is also why can't just statically list all datasources as producers: it's dynamic. Does that make sense? – Felk Jan 08 '18 at 18:24

1 Answers1

0

A Wildfly-specific solution is detailed here: https://docs.jboss.org/author/display/WFLY8/JPA+Reference+Guide#JPAReferenceGuide-BindingEntityManagerFactory%2FEntityManagertoJNDI. After following the steps described in the link, you should be able to obtain the reference to the EntityManager via JNDI (NamingContext.lookup()).

I still have the distinct feeling that you have an XY problem. Your comment adds to the confusion, as the statements 'I'm working on a JavaEE application which uses JPA' and 'The application using the library supposedly doesn't know about JPA' are mutually exclusive. Also, a 'persistence unit name, which happens to be implemented with JPA in one case' is misleading because a persistence unit is a concept specific to JPA.

I fail to understand why you 'can't just statically list all datasources as producers' but 'one global, application-scoped entitymanager' works fine as a workaround. Are persistence units not statically listed in persistence.xml? I hope the above link works for you, but if you add an example use case to your question, I can try to suggest a better solution if you like.

crizzis
  • 9,978
  • 2
  • 28
  • 47