Entity Manager Type and Associate Transaction - jpa

AFAIK, there are two types of entity manager.
1. Container managed entity manager
2. Application managed entity manager
Container managed entity manager
This type of em uses JTA transaction only
Below is my code:
#PersistenceContext(unitName = "", type = Transaction)
EntityManager em;
public void persist(T entity) {
em.persist(entity)
}
Questions:
There is exception throw when execute the code : TransactionRequireException
Why there is this kind of exception? There is no TransactionRequireException happen after added #Resource UserTransaction to the method persist(). I wonder UserTransaction is belongs to JTA right.
EntityTransaction et = em.getTransaction();
Refer to the above code, Why JTA transaction type cannot invokes getTransaction() ?
Can extended JTA Transaction em use outside of EJB?
Application managed entity manager
Utilize JTA Transaction
Utilize JDBC Transaction(Resource Local Transaction)
Please anyone provide example of source code on JDBC Transaction type.

A JPA persistence unit can either be JTA or RESOURCE_LOCAL.
If you use JTA, then you must use JTA for transaction, either through SessionBeans or by accessing JTA directly.
See,
http://en.wikibooks.org/wiki/Java_Persistence/Runtime#Java_Enterprise_Edition

Related

Does spring data jpa create new instance of EntityManager for each transaction?

I can't find information about relationship between EntityManager and transactions in spring data jpa application.
Which one of the statements is correct:
new instance of EntityManager is created per transaction
one shared instance of EntityManager is used for all transactions
The correct answer is: one shared instance of EntityManager is used for all transactions in the same persistence context.
We can have in consideration two things here:
First, the definition in the EntityManager Interface
An EntityManager instance is associated with a persistence context. A persistence context is a set of entity instances in which for any persistent entity identity there is a unique entity instance. Within the persistence context, the entity instances and their lifecycle are managed.
The set of entities that can be managed by a given EntityManager instance is defined by a persistence unit. A persistence unit defines the set of all classes that are related or grouped by the application, and which must be colocated in their mapping to a single database.
Second, the constructor of the Spring SimpleJpaRepository:
public SimpleJpaRepository(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
Assert.notNull(entityInformation, "JpaEntityInformation must not be null!");
Assert.notNull(entityManager, "EntityManager must not be null!");
this.entityInformation = entityInformation;
this.em = entityManager;
this.provider = PersistenceProvider.fromEntityManager(entityManager);
}
em is an attribute defined in that class with the final modifier:
private final EntityManager em;
And in the methods of the SimpleJpaRepository are made calls to that em without create new instances of the EntityManager.

Dynamic Datasources with JPA 2.1 and JTA on JBoss WildFly

I m getting mad with Jboss WildFly9 with JPA and JTA.
In my project requirements i have to implement multitenancy so i have to change dynamically datasource inside my persistence.xml.
Using jee approach this is not possibile so someone suggest me to use the classic:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("idelivery");
EntityManager em = emf.createEntityManager();
So till now it's working, i can create on by myself the enetitymanager and i can set jpa properties in a hashmap (included datasource).
Now i want to use JTA at least to handle transaction using transaction manager.
So these are the properties i set by code:
Properties properties = new Properties();
properties.put ("hibernate.dialect", "org.hibernate.dialect.Oracle10gDialect");
properties.put("javax.persistence.provider", "org.hibernate.jpa.HibernatePersistenceProvider");
properties.put("javax.persistence.transactionType", "JTA");
properties.put("javax.persistence.jtaDataSource", dataSourcePath);
Transaction type now is JTA. So i expect that i can use some code like:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("idelivery");
EntityManager em = emf.createEntityManager();
MyEntity exUser= new MyEntity();
try{
Context context = new InitialContext();
UserTransaction userTransaction = (UserTransaction)context.lookup("java:comp/UserTransaction");
userTransaction.begin();
em.persist(exUser);
userTransaction.commit();
Of course this code doesn't work at all as Hibernate rises an exception:
java.lang.NullPointerException at org.hibernate.engine.transaction.internal.jta.JtaStatusHelper.getStatus()
Telling me being not able to join a transaction at the creation of entity manager moment.
So ... how can i respect my project requirements... creating my own persistence with my dynamic datasouce and at the same time using the Transaction Manager?
Hibernate has its own solution for multi-tenancy. This is not part of the JPA standard, but it's compatible with and largely orthogonal to it.
It does work with managed persistence units and is compatible with JTA.
I've used the SCHEMA strategy successfully on WildFly 8.2.0.Final and 9.0.1.Final.
You just need to implement two helper classes and configure them in your persistence.xml.
If you can tell before hand how many datasources you would require then you can implement some kind of contextual selection of your entity managers by using CDI producer pattern.
Define all the possible datasources in your persistence.xml and then using some kind of producer singleton factory class to inject them based on their persistence unit.
Create a producer method which selects the correct entity manager based on your current context.
Then in your ejb or cdi beans get an instance of entitymanager through CDI injection
#Inject
private EntityManager em

Transaction needed if multiple EJB methods called?

My question is about the need to define a UserTransaction in a JSF Bean if multiple EJB methods are called.
This is my general scenario:
//jsf bean...
#EJB ejb1;
...
public String process(businessobject) {
ejb1.op1(businessobject);
ejb1.op2(businessobject);
....
}
both ejbs methods manipulate the same complex jpa entity bean object (including flush and detachment). I recognized in the database that some of the #oneToMany relations form my entity bean where duplicated when ejb1.op1() is called before ejb1.op2().
I understand that both ejbs start a new transaction. And to me anything looks ok so far.
But the JSF code only works correctly if I add a UserTransaction to my jsf method like this:
//jsf bean...
#Resource UserTransaction tx;
#EJB ejb1;
...
public String process(businessobject) {
try {
tx.begin();
ejb1.op1(businessobject);
ejb1.op2(businessobject);
finaly {
tx.commit();
}....
}
I did not expect that it is necessary to encapsulate both ejb calls into one usertransaction. Why is this necessary?
Each #Stateless EJB method call from a client (in your case, the JSF managed bean), counts by default indeed as one full transaction. This lasts as long as until the EJB method call returns, including nested EJB method calls.
Just merge them both into a single EJB method call if it must represent a single transaction.
public String process(Entity entity) {
ejb1.op1op2(entity);
// ...
}
with
public void op1op2(Entity entity) {
op1(entity);
op2(entity);
}
No need to fiddle with UserTransaction in the client. In a well designed JSF based client application you should never have the need for it, either.
As to the why of transactions, it locks the DB in case you're performing a business action on the entity. Your mistake was that you performed two apparently dependent business actions completely separately. This may in a high concurrent system indeed cause a corrupted DB state as you encountered yourself.
As to the why of transactions, this may be a good read: When is it necessary or convenient to use Spring or EJB3 or all of them together?
Is a user transaction needed for you? Generally, container managed transactions are good enough and serve the purpose.
Even if you need to have user managed transactions, it is not a good to have transaction management logic mingled with JSF logic.
For using container managed transactions, you should look at using the #TransactionAttribute on the EJBs.
If all the methods in your ejb need to have the same level of transaction support, you could have the annotation at the class level. Else you could also use the #TransactionAttribute annotation against each individual ejb method.

JPA, Entity from another persistenceContext as search argument

I have two entities:
#Entity
public class Entity1{}
#Entity
public class Entity2{
#OneToOne
protected Entity1 e1;
}
I have one method to search for Entity1
Entity1 findEntity1(some args){
EntityManager em = this.emfp.getEntityManager();
//perform search
return e1;
}
I use this method to find Entity2
Entity2 findEntity2(some args){
EntityManager em = this.emfp.getEntityManager();
e1 = findEntity1(args);
//perform search using e1 : Entity2.e1 = e1
return e2;
}
Each method has it's own EntityManager and therefore it's own Persistence context.
Could I use e1, returned from first method, in my second method?
While you cannot do it the way you are describing it - having different persistence contexts, you could do some tweaks to the code, effectively putting the entities in the same context. It depends on your stack if you can use all of them:
For an Java EE application, start the search from a session bean and use a container-managed EntityManager - this will wrap the persistence context in a transaction and both entities will be kept in the same context for the duration of the transaction.
For a Java SE application, you could still use transactions - UserTransactions. You would need to control the span of the transaction manually though.
Use an EXTENDED persistence context (since JPA 2.0). It only gets invalidated explicitly, so all the fetched entites will remain inside the context until you say so.
For all these solutions, you would need to change the EntityManager retrieval. Use the #PersistenceContext annotation in Java EE context and
#PersistenceUnit to retrieve the EntityManagerFactory in SE context
EDIT: It does not matter in how many EJBs you divide the search as long as you are staying inside the same transaction. As a rule of thumb, a transaction starts when the first EJB method is called and ends when this method returns. All methods invoked by this method will be in the same transaction.
This default behaviour may change though - the transactionality of EJB methods is defined by
#TransactionAttribute annotations, so simply follow the path of the call along your beans.
no, you can't use an entity from a different persistence context.
You'll need to expand the the select query and use basic types such as numeric ids or strings.

JPA, scope, and autosave?

I am using JPA and lets say I do something like this
public class MoRun extends Thread {...
public void run() {
final EntityManagerFactory emFactory = Persistence.createEntityManagerFactory("pu");
EntityManager manager = emFactory.createEntityManager();
manager.setFlushMode(FlushModeType.COMMIT);
someMethod(manager);
...
}
public void someMethod(EntityManager manager){
Query query = manager.createNamedQuery("byStates");
List<State> list = query.getResultList();
for (State state : list) {
if(someTest)
state.setValue(...)
}
...
}
So for those objects that pass "someTest" and values are updated are those changes automatically persisted to the db even though there is no transaction and I don't explicitly "manager.save(state)" the object? I ask because it seems like it is and I was wondering if the flush is doing it?
According to the javadoc of FlushMode (I'm assuming this is a JPA 1.0 question), and as pointed out by #Konrad:
If there is no transaction active, the persistence provider must not flush to the database.
Since you're very likely using a transaction-type="RESOURCE_LOCAL" for your persistence unit, since I don't see any begin/commit surrounding your calls to your EntityManager (which is not good, more on this just after), for me there is no transaction active so I wouldn't expect anything to be flushed.
Anyway, as reminded in the nice JPA Concepts page:
With <persistence-unit transaction-type="RESOURCE_LOCAL">
you are responsible for EntityManager
(PersistenceContext/Cache) creating
and tracking...
You must use
the EntityManagerFactory to get an
EntityManager
The resulting
EntityManager instance is a
PersistenceContext/Cache
An
EntityManagerFactory can be injected via the
#PersistenceUnit annotation only (not #PersistenceContext)
You are
not allowed to use #PersistenceContext to refer to a unit
of type RESOURCE_LOCAL
You
must use the EntityTransaction API to begin/commit around every call to your
EntityManger
Calling
entityManagerFactory.createEntityManager()
twice results in two separate
EntityManager instances and therefor
two separate PersistenceContexts/Caches.
It is
almost never a good idea to have more than one instance of an
EntityManager in use (don't create a
second one unless you've destroyed the
first)
So, in my opinion, you should fix your code here, there is no real point at wondering about unexpected behavior if your code is not correct. Just performs calls to your EntityManager inside a transaction.
How do you know there is no transaction? Are you using it from EJB? In that case I bet there is a transaction.
From docs (http://java.sun.com/javaee/6/docs/api/javax/persistence/FlushModeType.html):
If FlushModeType.COMMIT is set, the
effect of updates made to entities in
the persistence context upon queries
is unspecified.
If there is no transaction active, the
persistence provider must not flush to
the database.
If you are in transaction, attached entities (i.e. those loaded in the same transaction) are automatically recorded to database.