Handle multiple EntityManager in Java EE application - java

I have Java EE application with about 10 EntityManagers (number of EMs will probably increase). My application also contains many stateless, statefull and message driven beans.
Rather than inject in each bean my EMs with #PersistenceContext (and 2 methods to detect which EM to use for user), I probably store all of that inside a singleton bean and access it with others beans. Like that, no worries about maintainability.
Nevertheless, is it thread-safe to store EMs inside one singleton bean? Can a bottleneck appear?
Another solution is to create an abstract class and all beans will extend it.
What is the better solution?

An entity manager is not supposed to be thread-safe, so you shouldn't share ones via a Singleton. It's the same reason as why you should not inject an entity manager into a Servlet, and why a lookup from JNDI in such a web component -should- return a different instance of the entity manager ever time.
In practice some implementations may provide an entity manager that is thread-safe, so during testing it may seem to work. However, for the sake of portability and to protect you against upgrade woes, you should never rely on this.
Instead of inheriting from a common base class, you could define all your entity managers in one bean, and inject that wherever you need an entity manager.
E.g.
#Stateless
public class EntityManagerProviderBean {
#PersistenceContext(unitName="foo")
private EntityManager entityManagerFoo;
#PersistenceContext(unitName="bar")
private EntityManager entityManagerBar;
public EntityManager getEntityManager() {
return ...? entityManagerFoo : entityManagerBar;
}
}
(where ... is the logic you use to select the right entity manager)
Inject this into a bean needing an entity manager:
#Stateless
public class MyService {
#EJB
private EntityManagerProviderBean entityManagerProvider;
public void doStuff(MyEntity myEntity) {
entityManagerProvider.getEntityManager().update(myEntity);
}
}
Alternatively the following would perhaps be even neater:
#Stateless
#PersistenceContexts({
#PersistenceContext(unitName="foo", name = "fooENC"),
#PersistenceContext(unitName="bar", name = "barENC") }
)
public class EntityManagerProviderBean {
#Resource
private EJBContext context;
public EntityManager getEntityManager() {
return (EntityManager) context.lookup(... ? "fooENC" : "barENC");
}
}
The last example maps all persistence contexts into the ENC of the bean, where they can be conveniently retrieved programmatically.
Unfortunately, people forgot to add tests for the latter syntax to the TCK and subsequently major vendors forgot to implement it (see http://java.net/jira/browse/JPA_SPEC-38 and https://issues.jboss.org/browse/AS7-5549), so test if this works on your server.

Container managed entity managers are automatically propagated with the current JTA transaction and EntityManager references that are mapped to the same persistence unit provide access to the persistence context within that transaction. So it's not good practice to share an entity manager from a singleton, apart from concurrency problems, it would result in using the same transaction context for every method you call on your beans.
A simple solution to your need is to inject EntityManagerFactory references in your beans and create EntityManager objects calling the createEntityManager() method.
The drawback is that you should manage transactions manually, no more relying on the container.
Otherwise another approach could be inject all of your entity managers in a main enterprise bean and implement business logic in service beans with methods to which you pass the appropriate managers.
An example of the latter solution:
#Stateless
class MainBean {
#PersistenceContext EntityManager em1;
#PersistenceContext EntityManager em2;
...
#EJB WorkerBean1 workerBean1;
#EJB WorkerBean2 workerBean2;
...
void method1(Object param1, Object param2) {
workerBean1.method1(em1, param1, param2);
}
void method2(Object param1, Object param2, Object param3) {
workerBean2.method2(em2, param1, param2, param3);
}
...
}
#Stateless
class WorkerBean1 {
void method1(EntityManager em, Object param1, Object param2) {
...
}
...
}
#Stateless
class WorkerBean2 {
void method2(EntityManager em, Object param1, Object param2, Object param3) {
...
}
...
}

Composite persistence units - Java EE
The way to handle multiple entity managers, i.e. multiple persistence units, in Java EE is to use composite persistence units (CPUs). Such a composite persistence unit can be assessed from one single point in the EE web-application, a datalayer. This needs to be a #Stateless EE bean though in order to work with the #PersistenceContext.
Composite persistence units have been introduced to make possible reusing entity classes, among various Java applications. CPUs are a feature of Enterprise architecture. I choose to use EclipseLink as showcase, as I have positive experience with that from a running production application.
Introduction
In some cases, entities contain general data that is needed across more web-services in a server landscape. Take for example a general ‘name-address’ entity, a ‘user-password-role’ entity, a ‘document-keyword-index’ entity, etc. A composite persistence unit implementation facilitates that the source of each entity definition is specified in only one place (‘single point of definition’). These entity definitions can subsequently be included in each Java web-application that needs this entity access.
Working of composite persistence unit
The working of a composite persistence unit is illustrated by the following tutorial: EclipseLink composite persistence units
The concept of composite persistence units works by first defining member persistence units. Each member persistence unit may be associated with a different database, but the member persistence units can also all refer to the same actual database. I have experience with the latter, where EclipseLink (version 2.6.4) was used in combination with one Postgress database.
Maven is needed to make possible the required modular approach.
Settings in persistence.xml
A composite persistence unit member is defined as follows: Program a group of related entities (Java #Entity classes), one-by-one, in a dedicated Maven module. Define in this Maven module also a composite persistence unit member (important!). The composite unit member PuPersonData refers to this set of related entities that characterizes person data. Define the member persistence unit PuPersonData as (
<persistence-unit name="PuPersonData" transaction-type="JTA">
...
<jta-data-source>jdbc/PostgresDs</jta-data-source>
...
).
In a second Maven module, define another composite persistence unit member, PuWebTraffic (
<persistence-unit name="PuWebTraffic" transaction-type="JTA">
...
<jta-data-source>jdbc/PostgresDs</jta-data-source>
...
). Include here other entities (Java classes denoted with #Entity) that store data about web-transactions, logon, sessions, etc.
Needless to state, the two composite persistence unit members must be disjoint with respect to entities, no overlap is allowed in entity-names.
Both persistence unit members have in their XML-definitions the property:
<properties>
<property name="eclipselink.composite-unit.member" value="true"/>
...
</properties>
Composite persistence unit
We now define in a third Maven module the composite persistence unit CPuPersonSessionData that includes both the persistence units members PuPersonData and PuWebTraffic.
<persistence-unit name="CPuPersonSessionData" transaction-type="JTA">
This composite persistence unit CPuPersonSessionData refers to the two persistence unit members, PuPersonData and PuWebTraffic, by means of including the jars that result from compilation of the two pertaining Maven modules.
...
<jar-file>PuPersonData.jar</jar-file>
<jar-file>PuWebTraffic.jar</jar-file>
...
In the XML-definition of the composite persistence unit, the following property needs to be set
<properties>
<property name="eclipselink.composite-unit" value="true"/>
...
</properties>
This setting ensures that the composite persistence unit is treated differently by Java EE than its persistence unit members.
Use of persistence unit in Java
In the Java web-application that is going to store and retrieve entities with both person-data and traffic-data, only the composite persistence unit is included
#Stateless
public class DataLayer {
#PersistenceUnit(unitName="CPuPersonSessionData")
EntityManager em;
...
The normal 'em' operations such as persist, find and merge can now be performed on each entity, contained in one of the composite entity members.
Under Payara, no XA-transactions were needed for this composite persistence unit to address the entities pertaining to each of the persistence unit members.
Maven
The Maven parent POM file needs to contain the specifications for the pertaining modules.
...
<modules>
<module>PersonData</module>
<module>WebTraffic</module>
<module>PersonSessionData</module>
</modules>
...
The POM-file of each module needs to be configured as a normal Maven-project, referring to the parent POM-file.
Pitfalls:
You need to configure the Maven multi-module project correctly, which can be somewhat tricky. Each composite persistence unit member constitutes a separate Maven module. Also the composite persistence unit is a separate Maven module. The members need to be compiled first, in Maven sequence.
The ‘jars’ in the composite persistence unit need to be found when compiling the module of the composite persistence unit.
The entities of each composite persistence unit member need to be available in the resulting ‘jar’, directly in the ‘classes’ directory (adding extra paths to the entities, via Maven, is possible but complex).
The ‘jars’ of the persistence unit members need to be available in the ‘classes’ directory for the composite persistence unit to find them.
The benefit gained is a neat Enterprise data-layer that works with reusable entities, each with one central definition. Moreover, it is possible to perform cross-unit native SQL-queries. I got this to work also.
Documentation states that cross-unit native queries will not work when the composite persistence unit members run on different, actual databases. This should still be verified.

Related

Annotations in domain objects with JPA violates Database is a detail

What do you think about have persistence models and domain models separated? I've read that you don't have to mix persistence concerns with your business concerns (DDD, Clean Architecture,MartinFowler, Eric Evans and a lot and a lot of much more). Even so, I still see in all projects domain models annotated directly with ORM annotations like that, being the domain model coupled to the persistence mechanism reaching an anemic model and violating other principles.
//PersistenceJPA entity
#Entity
#Table(name="training_cycle")
class TrainingCycle {
#Id
private Long id;
private String name;
#Column(name="discipline_id")
#JoinColumn(name="discipline_id")
private Long disciplineId; //Referencing by Id because Discipline is another Aggregate ROOT
//EmptyConstructor, getters and setters avoided
}
//PersistenceJPA entity
#Entity
#Table(name="training_cycle")
class Discipline {
#Id
private Long disciplineId;
private String name;
//EmptyConstructor, getters and setters avoided
}
So if you want to follow clean principles you need to split Domain and Persistence Model(as shown below)to have Domain model with business behavior(this avoid anemic model and follows the SRP) and because of that you need to map the domain model to the persistence model (with typical methods like mapToEntity(DomainModel DM) and mapToDomain(PersistenceModel PM) maybe in a mapper/tranformer maybe in the repository class) when you want to interact with Datastore and viceversa when you want to retrieve data from database.
class Discipline {
private DisciplineId disciplineId;
private String name;
public Discipline(DisciplineId disciplineId, String name) {
this.disciplineId = disciplineId;
this.name = name
}
}
public class TrainingCycle{
private TrainingCycleId trainingCycleId;
private String name;
private DisciplineId disciplineId;
public TrainingCycle(TrainingCyleId trainingCycleId, String name, DisciplineId disciplineId) {
this.trainingCycleId = trainingCycleId;
this.name = name;
assignDiscipline(disciplineId);
}
public void assignDiscipline(DisciplineId aDisicplineId) {
if(aDisicplineId == null) {
throw new IllegalArgumenException("Discipline cannot be null")
}
this.disciplineId = aDisicplineId;
}
}
#Entity
#Table(name="training_cycle")
class TrainingCycleJpa {
#Id
private Long id;
private String name;
#Column(name="discipline_id")
#JoinColumn(name="discipline_id")
private Long disciplineId; //Referencing by Id because Discipline is another Aggregate ROOT
//EmptyConstructor, getters and setters avoided
}
#Entity
#Table(name="training_cycle")
class DisciplineJpa {
#Id
private Long disciplineId;
private String name;
//EmptyConstructor, getters and setters avoided
}
class TrainingCyleJpaRepository implements TrainigCycleRepository {
public void create(TrainingCycle trainingCycle) {
entityManager.persist(this.mapToEntity(trainingCycle)
}
public TrainingCycle create(TrainingCycleId trainingCycleId) {
return this.mapToDomain(entityManager.find(TrainingCycleId));
}
}
So the discussion/question is Split or not Split Persistence Model from Domain Model? When to split or when not? In the most projects, not to say in all the ones I've seen as an example, I've seen they couple annotations of persistence model in Domain Model when "gurus are allways hawking" DataStore is a detail.
Thanks a lot.
Please check out this very similar question: Are persistence annotations in domain objects a bad practice?
I think that as engineers we should be pragmatic. Any best practices, principles, or "guru suggestions" should help. They should not make things worse. So I suggest to treat them as guidance, not strict rules. For instance, I generally agree that "database is a detail". But we rarely change that detail.
On the other hand, annotations do not execute any code. And the coupling is not so bad. Your domain object can be a JPA entity at the same time, and it will be very clean and useful. By the way, this does not violate the Single Responsibility Principle (SPR). If you thought it does, check out SOLID explanation by its author Uncle Bob
EDIT
#RenéLink I don't agree: Annotations are interpreted and the code that executes them can be exchanged with a different interpreter even with a no-op interpreter. The annotation stays untouched and doesn't care. It's a declarative element, nothing more.
Annotations are source code dependencies, which means that the source code can not be compiled if the annotation is not present on the compile classpath.
It's right that annotations are not hard runtime dependencies. If the annotation class is not available on the classpath the annotation is also not available. Thus you can use bytecode that was compiled with annotations even if the annotations are not present on the classpath.
So annotations are a less restrictive dependency then normal classes, interfaces and so on.
I always try to minimize the dependencies in my code. Let's take a spring example.
In spring you can either implement InitializingBean or you can define a method annotated with #PostConstruct in this case I would use post construct. Often I don't need a #PostConstruct, because I do constructor injection. But if I move the initialization to a java config I can just call an arbitrary 'post construct' method befor returning the bean instance and I don't need a #PostConstruct annotation at all.
I agree that annotation dependencies are less problematic than other classes or interfaces. But keep in mind that the annotations the OP talks about also have another problem. If you mix domain objects with JPA annotations you violate the single responsibility principle. Your domain objects now have more then one reason to change (domain changes and persistence changes).
You will recognize the problem as soon as you add #Transient annotations or you might get merge conflicts because you changed domain logic and a colleague persistence things.
Yes, these annotations are details and should be kept away from the entities of the clean architecture.
Don't be confused about the name entity in the clean architecture and the #Entity annotation from your persistence framework. They are different things.
There is a video of Uncle Bob about clean architecture and at the end he makes it really clear, because he says:
the entities are not instances of database tables. They are usually constructions from many database tables.
In another video he talks about dependency injection and the annotations that these frameworks use. Well, dependency injection has nothing to do with persistence that you asked for, but this video makes clear what Uncle Bob thinks about framework annotations in the use case or entities layer of the clean architechture.
And in this video he makes it really clear that the entities should not have persistence details. It doesn't matter if it is hibernate or JPA.

How to change Persistence Unit dynamically?

I have a Spring MVC + Hibernate + JPA app. Also have 4 different Schemas in my db with similar tables. (for different companies) .
Now when I'm using my Hibernate app, can i switch Persistence Unit so
that I can use same the form (with the same content) to save data in
all four Schemas?
I'm aware that i can switch persistence unit at run time, but i want to be able to use the already loaded forms to save data to all four Schemas by changing the persistence unit.
I had similar problem some time ago.
I had 2 identical schemas - application had to persist to first or second depending on some logic.
It was pure Hibernate, but talking in terms of JPA I will suggest to have 4 persistence units defined in your persistence.xml:
persistence.xml
<persistence-unit name="PU1">
...
</persistence-unit>
<persistence-unit name="PU2">
...
</persistence-unit>
[...]
and DAO class that has injected EntityManager proxies - each for different PU:
#Repository
public class MyDaoImpl implements MyDao {
#PersistenceContext(unitName = "PU1")
private EntityManager em1;
#PersistenceContext(unitName = "PU2")
private EntityManager em2;
...
public void saveToPU1(MyEntity e) {
em1.persist(e);
}
public void saveToPU2(MyEntity e) {
em2.persist(e);
}
...
}
Of course em1 annotated with #PersistenceContext(unitName="PU1") is Spring's proxy to Hibernate session and becomes open and bound with current thread only if that thread tries to use it.
I am not sure to understand your problem: of course you can change the PersistentUnit used at runtime with the Persistence#createEntityManagerFactory(String persistenceUnitName) method.
But if you want to
save data to all four Schemas
Then you should repeat your operation (persist I guess) four times (for example in a private method taking the persistence unit name as parameter).
You could introduce a form cache if you want to reuse the already loaded forms, but this is a software architecture question.
As suggested in the Java EE 5 tutorial, on a software design point of view, having a form depending directly on the JPA layer is not a best practice. The other answer suggests it: a DAO could be the solution. All is about your DAOs lifecyle.
The Core JEE patterns book suggests it (the online reference only mentions briefly the topic, the printed book is better): associating DAOs with a Factory pattern is a good idea. You could recycle the EntityManagerFactory or anything you wish.

How to detect the type of a transaction: JTA or Resource Local from java code?

Is it possible to detect the type of a transaction (JTA or Resource Local) in Bean Managed Transaction using EclipseLink?
If yes, how can this be done?
Actually i need to detect the transaction type and the JNDI name aswell if possible in java class.
You can detect the type of transaction as follows;
EntityManager em = emf.createEntityManager();
boolean isJta = false;
try {
EntityTransaction et = em.getTransaction();
} catch (IllegalStateException ise) {
if (ise.getMessage().startsWith("A JTA EntityManager cannot use getTransaction")) {
isJta = true;
}
}
You might have to tweak the error message: this one matches what Hibernate (4.x) throws, EclipseLink probably throws a slightly different message (although probably the same exception class instance).
As for the JNDI name of the data source or persistence unit, that type of information, AFAIK, is not exposed by the JPA classes. You might be able to extract it by using EclipseLink (or for other ORM frameworks, ORM-framework-specific) methods. In other words, the EntityManagerFactory instance is of course an instance of an EclipseLink class that implements that interface. I would debug a test where you have an instance of the EMF and look through it's fields and properties.
Otherwise, you might be able to scan the JNDI catalog and pick out the right one, for example see the code here.

Initialize JPA-like entities with JDBC

I'm implementing several DAO classes for a web project and for some reasons I have to use JDBC.
Now I'd like to return an entity like this:
public class Customer{
// instead of int userId
private User user;
// instead of int activityId
private Activity act;
// ...
}
Using JPA user and activity would be loaded easily (and automatically specifying relations between entities).
But how, using JDBC? Is there a common way to achieve this? Should I load everiting in my CustomerDAO? IS it possible to implement lazy initialization for referenced entities?
My first idea was to implement in my UserDAO:
public void initUser(Customer customer);
and in my ActivityDAO:
public void initActivity(Customer customer);
to initialize variables in customer.
Active Record route
You could do this with AspectJ ITDs and essentially make your entities into Active Record like objects.
Basically you make an Aspect that advises class that implement an interface called "HasUser" and "HasActivity". Your interfaces HasUser and HasActivity will just define getters.
You will then make Aspects that will weave in the actual implementation of getUser() and getActivity().
Your aspects will do the actual JDBC work. Although the learning curve on AspectJ is initially steep it will make your code far more elegant.
You can take a look at one of my answers on AspectJ ITD stackoverflow post.
You should also check out springs #Configurable which will autowire in your dependencies (such as your datasource or jdbc template) into non managed spring bean.
Of course the best example of to see this in action is Spring Roo. Just look at the AspectJ files it generates to get an idea (granted that roo uses JPA) of how you would use #Configurable (make sure to use the activerecord annotation).
DAO Route
If you really want to go the DAO route than you need to this:
public class Customer{
// instead of int userId
private Integer userId;
// instead of int activityId
private Integer activityId;
}
Because in the DAO pattern your entity objects are not supposed to have behavior. Your Services and/or DAO's will have to make transfer objects or which you could attach the lazy loading.
I'm not sure if there is any automated approach about this. Without ORM I usually define getters as singletons where my reference types are initialized to null by default, i.e. my fetching function would load primitives + Strings and will leave them as null. Once I need getUser(), my getter would see if this is null and if so, it would issue another select statement based on the ID of the customer.

How to instantiate a class from string FQN in database in hibernate?

I'm trying to convert a legacy application to hibernate.
I have an entity that has a field, which should be instantiated to object instance based on a fully qualified name string in a database.
Consider the example below - if I have somePackageName.FirstClass in a database the someObject field should be an instance of FirstClass.
I guess I could use property access and persist / retrieve a string but that doesn't look very elegant to me.
I cannot use #PostLoad etc. - I'm using pure hibernate with spring (not JPA) - these annotations get ignored.
I know for example in MyBatis one can register a custom handler for field. Would anything similar be available in Hibernate?
I'm new to hibernate so I'm not really sure what the options are.
#Entity
class SomePersistentClass{
private SomeInterface someObject;
}
class FirstClass implements SomeInterface{
}
class SecondClass implements SomeInterface{
}
You can use JPA features such as #PostLoad, etc callbacks simply by enabling the proper Hibernate event listeners. Check the Hibernate EntityManager guide for details.
But this one is even easier. This is the role of a Type in Hibernate. First, you'll have to write an implementation of org.hibernate.type.Type or org.hibernate.usertype.UserType and specify that in #Type( type=... ) that handles the conversions (lots of web resources about writing custom Hibernate types). Then annotate your 'someObject' attribute with #Type( type="your.custom.TypeImpl" )

Categories

Resources