How to get the PersistenceUnit name for a given entity class?
I am developing a tool that handles some database entities using JPA2, with hibernate as the persistence provider. The tool is generic and uncoupled from any business logic, it takes a generic Class<? extends Task>
parameter to do its business, where Task is an interface that I created to say that the implementing entity has some behaviour interesting to my tool. The work of the tool includes getting instances of the given class from the database and manipulate some of their properties. Its a generic tool because it is being developed to be reusable and we have a large set of entity classes (but not all of the entities classes) that implements that interface (mainly those entities which models some types of running business tasks).
To do the tool's work, i need to get an EntityManager
for the given class. To get an EntityManager
, I need an EntityManagerFactory
. To get an EntityManagerFactory
, I need the persistence unit name.
So, my problem is that given a entity class, get the name of its persistence unit. However I did not found any way to do this without an already existing EntityManager for that persistence unit, which creates a chicken-or-egg-first, key-locked-inside-the-chest problem.
A partial solution is to pass the name of the persistence unit along with the entity class, but this looks wrong because the name of the persistence unit should be inferred (or at least guessed) from the given class. This could be optimized to something like putting the name in an annotation on the entity class, but this still looks like an improper solution. Searching and analyzing the persistence.xml
file is something that we really want t开发者_JS百科o avoid.
So, what can I do to solve this? Any ideas?
I'm pretty sure that it's impossible to determine the persistence unit an entity class is associated with because JPA's design is the other way around: normally you inject one EntityManagerFactory for a specific persistence unit.
If you have at least the names of all available persistence units you could create all available factories using Persistence.createEntityManagerFactory(persistenceUnitName)
and then check whether a certain class belongs to a unit using its meta model:
for (EntityManagerFactory emf : factories) {
try {
EntityType<?> entity = emf.getMetamodel().entity(classToCheck);
// bingo
} catch (Exception e) {
// wrong persistence unit
}
}
Or you inspect MetaModel.getEntities() and build a mapping of unit name to managed entity classes.
Wow, I dot not think there is a perfect way to do the things just the way you describe it.
The only source of static information regarding the relationship of the entities within a particular persistence unit is the persistence.xml file, provided that you declared the entity classes there, because you could omit them and let the persistence manager find them all for you.
Perhaps you could organize your code in such a way that it would make evident to which persistence unit a given class belongs. For instance, you could organize packages per persistence unit, or you could create a custom Java annotation with the persistence unit to which a given class belongs, and then read the annotation at runtime.
How does that sound?
These ideas are just a way to replicate, with a different static strategy, what the persistence.xml should already know.
精彩评论