ResourceLocal to JTA - java

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

Related

Persistence Unit not started, when only using #Transactional

I am using Wildfly 10.1.0 and I am trying to change all the EJB's to only use #Transactional annotations, which are provided since Jave EE 7 (because of JTA 1.2). The thing is when my project has 0 EJB's, the PersistenceUnit is not started by the container. If I add an empty class with only the annotation #Stateless then it works again.
This is my persistence.xml
<persistence version="2.1">
<persistence-unit name="Storage-PU" transaction-type="JTA">
<jta-data-source>java:/PostGreDS</jta-data-source>
<class>SomeEntity<class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
</persistence-unit>
</persistence>
What is the reason why the PersistenceUnit is not started, when there are no EJB's available?
What is the reason why the PersistenceUnit is not started, when there are no EJB's available?
The reason is that in a JEE application the Persistence Context (including DB connection, Persistence Units and stuff) is started and managed by the EJB container:
So, just annotating beans methods at the Web tier with #Transactional is not enough to get Persistence Context started. Beware that transactions are also managed by the EJB container, not the Web Container.
See Java Platform, Enterprise Edition: The Java EE Tutorial for further details on JEE architecture.

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.

Running tests with EJB Container and JPA

I'm suffering in understanding how to properly set up tests in JUnit for EJB and JPA. I've seen advices telling to use Arquillian for the integration test, but I want to do a simple unit test.
What I have right now is a EJB with injects a Persintance Context. I run the application in Wildfly 9 and have the datasource configured there, so my persistance file looks like this:
<jta-data-source>java:jboss/datasources/MyDataSource</jta-data-source>
<properties>
<!-- Properties for Hibernate -->
<property name="hibernate.hbm2ddl.auto" value="create" />
<property name="hibernate.show_sql" value="false" />
</properties>
Now if I added glassfish-embedded-all to my test dependencies to run the embeded EJB container and created a simple test:
Map<String, Object> properties = new HashMap<>();
properties.put(EJBContainer.MODULES, new File("target/classes"));
EJBContainer container = EJBContainer.createEJBContainer();
TestEJb bean = (TestEJb) container.getContext().lookup("java:global/classes/TestEJb");
assertNotNull(bean);
assertEquals(1,bean.test());
Then I receive the error as the EJB contains the refence to the MyDataSource which is not known by the container. Should I create another persistance unit and pass it somehow to the EJB?
What is the right way to do it?
The issue here is that you don't have an application context so the lookup is failing. Usually for unit testing container resources you use a mock object such as mockejb.
Lots of examples out there if you search for mockejb examples.

JPA; Setting 'transaction-type' on annotation

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();

What do values in persistence.xml mean in EJB?

I am new to Java and JBoss and JDeveloper. My legacy project has this persistence.xml file:
<persistence-unit name="DoDSRMGR">
<jta-data-source>java:/DoDSRDS</jta-data-source>
<class>dodsr.ManifestsPass1</class>
<class>dodsr.model.ManifestsPass2</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
<property name="javax.persistence.jtaDataSource" value="java:/DoDSRDS"/>
</properties>
</persistence-unit>
</persistence>
My questions are what do the values in the file mean and what are they for? Also, where does this file belong in the EAR file META-INF or the JAR file META-INF?
What is the significance of the name="DoDSRMGR" designation, is this the name of the bean when I call from a Java program or is it the application name? Also what is the "java:/DoDSRDS" do?
Is this the way to call the bean from a desktop application:
( DodsrUserSessionEJB) ctx.lookup("/dodsr/"+ejbName+"/remote");
<persistence-unit name="DoDSRMGR"> This line lets you put a name to a persistence unit. You use the persistent unit name when you want to instantiate an EntityManager in this way:
EntityManager eMgr = Persistence.createEntityManagerFactory("Your persistence unit name").createEntityManager();
An EntityManager is the object that helps you select, persist, update and remove your JPA entities from/into the database.
<jta-data-source>java:/DoDSRDS</jta-data-source> This line tells you how you are going to manage the persistence transactions (persist, update and remove entities). If you don't specify this line, every time you want to persist, update or remove an entity from the database, you have to first get a transaction instance and call begin() after you persist/update/remove your entity and after that you call the commit() method.
Since you already have the jta-data-source element in your XML you don't need to manually call the begin() and commit() methods. Your application server manages the transactionality via a transaction resource identified by the value "java:/DoDSRDS"
This XML file can be placed in either META-INF or WEB-INF folder.

Categories

Resources