Persistence Unit not started, when only using #Transactional - java

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.

Related

StandAlone CDI + JTA Without JNDI

I am using CDI + DeltaSpike + Camel in a standalone app.
Here is my current setup :
persistence.xml
<persistence 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_2_0.xsd"
version="2.0">
<persistence-unit name="primary" transaction-type="RESOURCE_LOCAL">
<shared-cache-mode>DISABLE_SELECTIVE</shared-cache-mode>
</persistence-unit>
Custom properties on EntityManagerFactoryProducer:
properties.put("hibernate.connection.provider_class", "org.example.HikariConnectionProvider");
I'm using DeltaSpike JPA Transaction with (https://deltaspike.apache.org/documentation/jpa.html):
org.apache.deltaspike.jpa.api.transaction.TransactionScoped;
org.apache.deltaspike.jpa.api.transaction.Transactional;
I would like to use Infinispan to sync my app caches.
According to Infinispan doc:
"It is highly recommended that Hibernate is configured with JTA transactions"
How can I use JTA transactions ?
I tried to change "RESOURCE_LOCAL" to "JTA" but I don't understand what am I supposed to configure for :
hibernate.transaction.factory_class
hibernate.transaction.jta.platform
I am not using JNDI, and I am not in an application server.
Also, I would like to use #javax.transaction.Transactional instead of DeltaSpike.
Essentially, you are asking how to use most Java EE features without using a Java EE container.
Of course, there are JTA implementations like Atomikos you can embed in a "standalone" application.
On the other hand, it might be a lot easier to start with a full-blown Java EE environment and then ignore or exclude anything you don't need.
App servers are rather lightweight these days, and if a self-contained executable is a must-have for you, then have a look at WildFly Swarm or Payara Micro.

WebSphere 7 Entity Manager creation issue with Hibernate Provider?

I keep getting
The server cannot create an EntityManagerFactory factory for the default persistent unit from the org.hibernate.ejb.HibernatePersistence provider
when I try to run the web application(.war) on the WebSphere 7 + Oracle .This worked well so far under the tomcat + MySql.
my persistance.xml's config
<persistence-unit name="default">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<non-jta-data-source>src/test</non-jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.Oracle10gDialect"/>
<property name="hibernate.hbm2ddl.auto" value="validate"/>
<property name="hibernate.connection.release_mode" value="after_transaction"/>
</persistence-unit>
There were several solutions for this, after googling. But there was no luck even after trying them for about 2 days.
To fix this issue do we need to install any fix-pack in WebSphere?
Please find the stack-trace files in below link.
https://www.ibm.com/developerworks/community/forums/html/topic?id=e54136aa-fbe0-4576-a41c-4b438475f0a5
In WebSphere v7 to use container managed JPA you need to install feature pack for JPA and it will only support JPA 2.0.
Based on your logs it looks like you are using Hibernate 4.3 which is JPA 2.1.
You cant use that with classic WebSphere Application Server, see Deploying application using Hibernate JPA 2.1 to IBM WebSphere for more details.
So you either would need to downgrade to Hibernate 4.2, use application managed Entity manager, or migrate to WebSphere Liberty Profile server 8.5.5.6 or later which fully supports JPA 2.1.
If your application works on Tomcat, I'd suggest trying WebSphere Liberty, which is also lightweight, developer friendly server, available to download for free - https://developer.ibm.com/wasdev/

JPA Container persistence unit Vs JPA Non-container persistence unit

I am new to JPA and in many resources of JPA I encounter these two term(Container persistence unit and Non-container persistence unit) but I can not understand differences.Can anybody help me understand these phrases? what is the container ?is it something like
Tomcat?
'Container' in this context means an EJB container, which is usually provided by a Java EE compliant application server.
Since Tomcat is not Java EE compliant, it is not a 'container' in the sense of the JPA spec. Tom EE however provides such a container as do other Java EE servers. Oracle provides a complete list of compliant servers.
The main difference is that in a container you can use JTA resources like transactions and a transaction-scoped EntityManager. Without a container you have to use ÈntityTransaction and an EXTENDED EntityManager.
In the attribute transaction-type can take one of the 2 values "RESOURCE_LOCAL" or "JTA".
JTA - Works on an application server environment. Transaction managed by the application server.
RESOURCE_LOCAL - You managed the transaction with your code. You can use this to work standalone during the development / testing phase.

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.

EntityManager injection results in NullPointerException

I'm writing my first Java EE (EJB + Servlets etc.) application (please note: I'm using Eclipse).
I'm stuck with a problem with EntityManager injection not working, and having some difficulties finding why due to my Java EE (and Java in general) noobness.
Here is my persistence.xml file - I think this is mostly correct, since I can launch the HSQL database manager from the JMX console and my PUBLIC.USER table shows up correctly.
<?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="MyPu">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/DefaultDS</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
</properties>
</persistence-unit>
</persistence>
Here's my servlet code:
[...]
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws
String id = request.getParameter("username");
String password = request.getParameter("password");
UserManagerBean um = new UserManagerBean();
um.register(username, password);
RequestDispatcher dispatcher=getServletContext().getRequestDispatcher("/index.jsp");
dispatcher.forward(request, response);
}
And here's my UserManagerBean Class:
//bunch of imports
import myPackage.UserManager;
public #Stateful class UserManagerBean implements UserManager {
#PersistenceContext(unitName="MyPu")
private EntityManager persistManager;
public void register(String username, String password) {
User user = new User(userame, password);
persistManager.persist(user);
persistManager.flush();
}
}
The persistManager.persist(user) line throws a NullPointerException.
From my own searching I understood that this is happening because, since I'm calling new() on UserManagerBean the injection from the #PersistenceContext annotation never takes place and persistManager never gets bound.
If so, it is evident that I'm missing something about the proper usage of EJBs.
What is the right way to instantiate my bean? What's with the interfaces? I'm not entirely sure if my bean should be stateful or stateless :\
Additional info:
I changed code in my servlet, from
UserManagerBean um = new UserManagerBean();
to
#EJB
private UserManagerBean um;
in the appropriate place. Now um is the NullPointer.
Quoting Referencing EJB3 Session Beans from non-EJB3 Beans from the JBoss documentation:
JBoss Application Server 4.2.2 implemented EJB3 functionality by way of an EJB MBean container running as a plugin in the JBoss Application Server. This had certain implications for application development.
The EJB3 plugin injects references to an EntityManager and #EJB references from one EJB object to another. However this support is limited to the EJB3 MBean and the JAR files it manages. Any JAR files which are loaded from a WAR (such as Servlets, JSF backing beans, and so forth) do not undergo this processing. The Java 5 Enterprise Edition standard specifies that a Servlet can reference a Session Bean through an #EJB annotated reference, this was not implemented in JBoss Application Server 4.2.2.
So even though the Java EE 5 specification stipulates a wider scope of the #EJB annotation, JBoss 4.2.2 doesn't support it. In fact JBoss 4.2.2 is a transitional version that doesn't claim full Java EE 5 compliance.
Consequently, either:
Stick with you actual version of JBoss but use a JDNI lookup to get your bean - or -
Swith to JBoss 5 AS that fully supports the entire Java 5 Enterprise Edition specification (but has horrible startup performances) - or -
Swith to another Java EE 5 application server like GlassFish v2 (or even v3) or WebLogic 10. I'd go with GFv3.
As Petar Minchev said in the comments above #EJB doesn't work in servlets with JBoss 4.2.
In your WAR (in the WEB-INF directory) you'll need to modify two files:
web.xml:
<ejb-local-ref>
<ejb-ref-name>ejb/UserManager</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local-home/>
<local>myPackage.UserManager</local>
</ejb-local-ref>
jboss-web.xml:
<?xml version='1.0' encoding='ISO-8859-1'?>
<!DOCTYPE jboss-web PUBLIC "-//JBoss//DTD Web Application 2.3//EN" "http://www.jboss.org/j2ee/dtd/jboss-web_3_2.dtd">
<jboss-web>
<ejb-local-ref>
<ejb-ref-name>ejb/UserManager</ejb-ref-name>
<local-jndi-name>[earname]/UserManagerBean/local</local-jndi-name>
</ejb-local-ref>
</jboss-web>
You can then get an instance of your EJB by doing:
UserManagerBean um = (UserManager)new InitialContext().lookup( "java:comp/env/ejb/UserManager" );
As per the comments, it turns out that you indeed are using an appserver which doesn't support it at all -as I expected. To resolve this, you have 3 options:
Use "good old" XML config files.
Upgrade the server (there's already a stable 5.1.0).
Replace the server (I can recommend Glassfish v3 to be the most up-to-date).
To enable dependency injection on your project make sure that you have the file "beans.xml" and it is properly located.
For WAR packaging the location is src/main/webapp/WEB-INF/
For JAR and EAR packaging the location is src/main/resources/META-INF/
If you have several maven modules you must have it on each module.
More information about beans.xml

Categories

Resources