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.
Related
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();
I am trying to update a small alpha version of a enterprise application originally written in Java6. Now I want to use:
Java 7
JSF latest
Maven
EJB 3.2 with Glassfish
So far I can deploy my EAR file on Glassfish without problems. My webapp can be loaded, the first JSF pages navigate fine. And my JSF backing bean seems to also load my Stateless session beans fine. Debugging showed me, I can get from one SSB to another coming from my backing bean. The last and final step that I am missing is my entity manager and persistence.
My class is annoated with #Stateless and i am using:
#PersistenceContext(unitName = "myProjectPU")
protected EntityManager entityManager;
But the entity manager is null :(
My persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="myProjectPU" transaction-type="JTA">
<jta-data-source>jdbc/myProject</jta-data-source>
<properties>
<property name="javax.persistence.schema-generation.create-database-schemas" value="true" />
</properties>
</persistence-unit>
</persistence>
Any ideas? Does the persistence.xml have to be inside the ear maven module? Right now its in the ejb maven module, where my classes which use the entity manager reside.
Well finally I found the problem. Scrolling up in the glassfish logs showed that the nullpointer exception followed up an earlier exception that stated "No database selected". The problem was not in the code, but in the Glassfish JDBC Connection that I made. My ping worked fine and i thought the connection was ok. But you dont only have to add the mysql port and username and password. You also MUST change the default URL and add (additional properties in connection pool) the following value:
jdbc:mysql://localhost:3306/yourdatabase
before it was defaulted to:
jdbc:mysql://:3306/
Take also care that there are two parameters, Url and URL! After that not only the ping succeeded, but also the database connection with entity manager worked fine. :(
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
I have read other topics but didn't find a good and clear answer
What I'm trying to is to develop a web app which is able to:
1) Log/track user events in a seperate UI database which we connect via hibernate with the same database schema (maybe save connectionString to the different oracle databases)
2) At runtime when you log in you can choose an environment to connect to one of the three different oracle databases that have the same schema (but not the same data)
3) provide the correct DataSource with username and password (where to get this sensitive data? I would not keep this stored somewhere in the application)
I'm fairly new to the Spring framework. I found this link which could be a first lead.
Any suggestions?
Also using Spring 3.1 or 3.2, JDBC to query to my oracle database and hibernate mapping to my UI database. This sounds quite confusing so I have a picture:
infrastructure
Just create different DAOs each with a separate persistence-unit attached to them.
In your persistence.xml you can have multiple persistence-unit's each connecting to a different database.
Example:
public class Dao1{
#PersistenceContext(unitName="Database1")
protected EntityManager entityManager;
public class Dao2{
#PersistenceContext(unitName="Database2")
protected EntityManager entityManager;
<?xml version="1.0" encoding="UTF-8"?>
<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_1_0.xsd"
version="1.0">
<persistence-unit name="Database1">
<exclude-unlisted-classes />
<properties>
</properties>
</persistence-unit>
<persistence-unit name="Database2">
<exclude-unlisted-classes />
<properties>
</properties>
</persistence-unit>
</persistence>
The link you have mentioned in your post says following:
1) create different data sources pointing to different schema.
2) extends AbstractRoutingDataSource and create your own data source, override determineCurrentLookupKey method which will provide value of key. in your case it will return whatever user choose from UI. also in the bean definition of your custom data source pass all the data source as map with key as option available at UI.
3) Now assign this data source into your session factory bean.
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