JPA; Setting 'transaction-type' on annotation - java

I'm using Eclipselink's implementation of JPA and this is how I'm instantiating persistence context:
#PicketLink
#PersistenceContext(unitName = "txPersistUnit.security")
private EntityManager txEmSec;
this is persistence unit defitnition:
<persistence-unit name="txPersistUnit.security" transaction-type="RESOURCE_LOCAL">
...
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.target-database" value="PostgreSQL"/>
<property name="eclipselink.cache.shared.default" value="true"/>
...
<!-- EclipseLink should create the database schema automatically -->
<property name="eclipselink.ddl-generation" value="create-or-extend-tables"/>
<property name="eclipselink.ddl-generation.output-mode"
value="database"/>
</properties>
</persistence-unit>
so, you can see I am setting RESOURCE_LOCAL as a transaction-type but I'm getting this error when deploying:
java.io.IOException: com.sun.enterprise.admin.remote.RemoteFailureException: Error occurred during deployment: Exception while preparing the app : The persistence-context-ref-name [com.txsolutions.manager.PersistenceManager/txEmSec] in module [txAPI] resolves to a persistence unit called [txPersistUnit.security] which is of type RESOURCE_LOCAL. Only persistence units with transaction type JTA can be used as a container managed entity manager. Please verify your application.. Please see server.log for more details.
Server is Glassfish 4.0.1
Question is why is glassfish not deploying this application succesfully when transaction-type set to RESOURCE_LOCAL?
I'm emphasizing that I have RESOURCE_LOCAL persistence unit in that same application on that same server deployed.
Now, when I create entity manager like this:
..declarations omitted..
factory = Persistence.createEntityManagerFactory("txPersistUnit.security");
entityManager = factory.createEntityManager();
it is created sucessfuly even with RESOURCE_LOCAL as for transaction type.
So all in all whats the difference between this two approaches?
Thanks!

Since you are running your code in an JEE compliant Application Server (i.e. Glassfish), your transaction type should be JTA.
<persistence-unit name="txPersistUnit.security" transaction-type="JTA">
RESOURCE_LOCAL is generally used for Standalone Java SE applications.
Since you are using #PersistenceContext, means that you are using a Container-Managed entity manager/persistence context. Since it is container-managed, it requires you to set your transaction type to JTA.
I suggest you try using an Application-Managed persistence context. Use #PersistenceUnit to inject an instance of EntityManagerFactory, then from the factory create the entity manager. Example below.
#PersistenceUnit(unitName="txPersistUnit.security")
EntityManagerFactory emf;
....
// somewhere in your code
EntityManager em = emf.createEntityManager();

Related

EntityManager is always null on REST project (netbeans) running on weblogic 12c

I've been working on a REST project on Netbeans 8.2 (compiled using Java 1.7). I'm deploying my web project on a Weblogic Server 12.1.2 and using JPA (w/ Eclipselink) as the persistence engine referencing a JTA datasource that is configured on server.
The problem I have is common from what I investigated in google; however, I was not able to find any solution on the Web that helps me with the issue.
Basically, this is how my persistence.xml file is defined:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="gchPermissionPU" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc.vz.customer.ds</jta-data-source>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="eclipselink.target-server" value="WebLogic"/>
<property name="javax.persistence.query.timeout" value="660000"/>
<property name="eclipselink.logging.level" value="ALL"/>
<property name="eclipselink.persistence-context.flush-mode" value="COMMIT"/>
<property name="eclipselink.cache.shared.default" value="false"/>
</properties>
</persistence-unit>
</persistence>
This is how I use the EntityManager on a class:
#PersistenceContext(unitName = "gchPermissionPU")
protected EntityManager entityManager;
I get the NullPointerException whenever this line is called (the only one in which I reference entityManager by now):
Query permissionsQuery = entityManager.createNativeQuery(nativeSqlQuery.toString());
I believe the NullPointer comes up because the entityManager variable is null.
Here's the basic data source configuration on my weblogic:
I wonder if I need some kind of additional configuration in the weblogic side or any missing piece of code.
Thanks in advance for your time and help. Any clue/feedback is appreciated.
I managed to solve my problem by manually creating EntityManagerFactory and EntityManager, from this answer:
PersistenceContext EntityManager injection NullPointerException
Seems like without EJB references, you need to force the creation of your persistence components. So my team came up with the following solution:
//1. Define the components required for persistence:
#PersistenceUnit(unitName = "gchPermissionPU")
private EntityManagerFactory entityManagerFactory;
private EntityManager entityManager;
//2. Just a method that will create entity manager factory if it is "null"
public final EntityManager getEntityManager() {
if (entityManagerFactory == null) {
entityManagerFactory = Persistence.createEntityManagerFactory("gchPermissionPU");
}
if (entityManager == null) {
entityManager = entityManagerFactory.createEntityManager();
}
return entityManager;
}
However, I wonder to know if this is the best solution for a Web application that will be used by > 1000 users. I can't believe that a Web application should rely on EJB for injection (maybe because it is Weblogic) but I remember I implemented a similar application on Tomcat some time ago and didn't need to make this "workaround".
If somebody has additional comments or feedback, please let me know.
Thanks.

ResourceLocal to JTA

I am developing an web application and I have to use JTA which I never used. I started using EntityManager but it seems not to work here. When I use EntityManager I get this message:
Only persistence units with transaction type JTA can be used as a container managed entity manager.
To cut it short, I have this piece of code:
#PersistenceContext(unitName = "zJSF2PU")
private EntityManager em;
em.getTransaction().begin();
//some code
em.getTransaction().commit();
How can I do this without EntityManager?
In your ejb project META-INF/persistence.xml you must have something like:
<?xml version="1.0" encoding="UTF-8"?>
<persistence>
<persistence-unit name="myPersistenceUnitNamePersonalised" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/MySQL</jta-data-source>
<properties>
<property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
<property name="eclipselink.ddl-generation.output-mode" value="database" />
<property name="eclipselink.logging.level" value="FINE" />
</properties>
</persistence-unit>
</persistence>
And you must declare this in your Application Server (jboss, tomcat, glassfish)
You need to search how to add a data-source and persistence unit in your Application Server...
And that's it... they comunicate thru jndi
Remove transaction-type="RESOURCE_LOCAL" from your persistence.xml.
Remove calls to em.getTransaction(). Inject javax.transaction.UserTransaction (JTA) and use its begin/commit/rollback methods. Alternatively, inject the EM into a stateless EJB instead, and allow the EJB container to automatically manage the transaction.
I finally was able to fix my problem. From my searches it resulted that you can not use EntityManager when you are using JTA within ManagedBeans for example. However it can be used in a stateless bean and then we can inject this Stateless Bean to the ManagedBean and use its methods. The procedure is as follows:
create an EJB (a simple class with #Stateless annotation)
move the method that uses EntityManager to the EJB
inject the EJB into your managed bean (using #EJB annotation) and call the relevant method
For more information refer to this other post: JTA & MySQL

Deploying on jboss using getCurrentSession

I have implemented DAO's based on Link in the HibernateDAOFactory class, there is a method
protected Session getCurrentSession() {
return HibernateUtil.getSessionFactory().getCurrentSession();
}
To implement the same i have made the hibernate.cfg.xml changes as described in the below articles Here 1
HERE 2
<property name="transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property><br/>
<property name="transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup</property>
<property name="hibernate.current_session_context_class">thread</property>
While deploying it on jboss i get the following errors
org.hibernate.TransactionException: could not register synchronization
I even set the property
<property name="hibernate.current_session_context_class">jta</property>
but i got the following error.
Caused by: org.hibernate.HibernateException: Unable to locate current JTA transaction
at org.hibernate.context.JTASessionContext.currentSession(JTASessionContext.java:88)
at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:574)
Am i missing something out here??
My jboss version is 4.2.3 and hibernate version is 3.3.1 and using Java 7.
Well for thread based session management I removed the transaction.factory_class and manager_lookup_class property from my hibernate.cfg.xml and it worked like a charm.
But for jta based session management, I am still getting the same error.

Two phase commit transaction in Java EE 5

I want to know that how can I do two phase commit transaction by using Java EE5...I am using EJB with JPA which has hibernate configured with MySql. I just want to use JAVA EE specification for transaction not using hibernate or JDBC specific object....
All you need to do, to ensure that JTA transactions are used to perform all transactional work in JPA, is to specify that the Persistence Unit type is JTA, and designate a JTA datasource for use by the JPA provider. Your persistence.xml file would have contents similar to the following:
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<!-- Specifies the type of the entity managers used by the persistence unit,
as a JTA entity manager -->
<persistence-unit name="example-pu" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<!-- Specifies a JTA datasource for use by the JPA provider.
All connections obtained by the JPA provider for this persistence unit
will be from this datasource -->
<jta-data-source>jdbc/myDS</jta-data-source>
...
</persistence-unit>
</persistence>
Additionally, you must ensure that the datasource defined in the jta-data-source attribute, does not employ optimizations like allowing local transactions. In simpler words, all transactions involving the said datasource must be XA transactions, or the datasource must be an XA datasource without any support for local transactions.
Note that merely specifiying a JTA data source is not sufficient. You must define the persistence unit as one requiring the use of JTA entity managers, as an undefined value for the transaction-type attribute, depends on the environment in which the JPA provider operates. If the provider operates in a Java EE environment, JTA entity managers will be created, where as RESOURCE_LOCAL entity managers will be created in a Java SE environment.
Also, note that, if you specify the transaction-type as RESOURCE_LOCAL, then in a Java EE environment, the JPA provider will ignore the jta-data-source value, and will instead rely on the non-jta-data-source value for creating connections.

how to configure cache in hibernate with jboss? ? And test as well in kumud console?

Does any one know, how to configure cache for hibernate with jboss ?
My clear question is I am using JPA and Jboss. Every time I call JPA method its creating entity and binding query.
My persistence properties are
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
<property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.SingletonEhCacheProvider"/>
<property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.cache.use_query_cache" value="true"/>
And I am creating entity manager the way shown below:
emf = Persistence.createEntityManagerFactory("pu");
em = emf.createEntityManager();
em = Persistence.createEntityManagerFactory("pu")
.createEntityManager();
Is there any nice way to manage entity manager resource insted create new every time or any property can set in persistance. Remember it's JPA.
The question is not clear, there are many second level cache providers for Hibernate and they are not application server specific.
To enable the second level cache, you need to set the following properties in Hibernate configuration file hibernate.cfg.xml:
<property name="hibernate.cache.use_second_level_cache">true</property>
And if you want to also enable query result caching:
<property name="hibernate.cache.use_query_cache">true</property>
Then, declare the name of a class that implements org.hibernate.cache.CacheProvider - a cache provider - under the hibernate.cache.provider_class property. For example, to use JBoss Cache 2:
<property name="hibernate.cache.provider_class">org.hibernate.cache.jbc2.JBossCacheRegionFactory</property>
Of course, the JAR for the provider must be added to the application classpath.
That's for the Hibernate side. Depending on the chosen cache provider, there might be additional configuration steps. But as I said, there are many second level cache providers: EHCache, JBoss Cache, Infinispan, Hazelcast, Coherence, GigaSpace, etc.

Categories

Resources