JPA Unknown Source - java

I'm creating my first JPA application using NetBeans. I'm unable to make the persistence work. The connection to database works well, when I run the application the database tables got created. But when I try to create EntityManagerFactory:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("PISProjektPU");
I get:
INFO: javax.persistence.PersistenceException: [PersistenceUnit: PISProjektPU] Unable to build EntityManagerFactory
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:677)
at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:126)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:78)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
at cz.vutbr.fit.pis.spravaTechniky.service.TestManager.<init>(TestManager.java:28)
at cz.vutbr.fit.pis.spravaTechniky.service.__EJB31_Generated__TestManager__Intf____Bean__.<init>(Unknown Source)
...
My persistence.xml file looks like this (generated by NetBeans, I didn't change anything):
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.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_2_0.xsd">
<persistence-unit name="PISProjektPU" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>jdbc/myslq_spravaTechniky</jta-data-source>
<class>cz.vutbr.fit.pis.spravaTechniky.data.TestEntity</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
</properties>
</persistence-unit>
</persistence>
and it's located here:
src/conf/persistence.xml
build/web/WEB-INF/classes/META-INF/persistence.xml
I searched the forum and found some tips how to remove this error, but I was unable to make it work. I tried to add these two lines to Manifest.mf:
Meta-Persistence: META-INF/persistence.xml
JPA-PersistenceUnits: PISProjektPU
I tried to move the persistence.xml file to all possible locations. I also added all libraries that seemed like they might be useful, when I go to Properties/Libraries, I see:
Java EE 6 API Library
Hibernate
Java-EE-GlassFish-v3
EclipseLink(JPA 2.0)
EclipseLink-GlassFish-v3
Hibernate JPA
JSF 2.0
Java EE Web 6 API Library
Persistence
I'm sure I'm doing some stupid simple mistake, but after a day trying to make this work I am unable to see where is the problem. To be honest right now I'm just totally confused about where to put which file or how to configure everything, so I'm randomly trying different things. I will be thankful for any advice!
Edit:
Thanks for the suggestion. My test classes actually look like this:
Class TestManager:
#Stateless
public class TestManager {
#PersistenceContext
private EntityManager em;
public void save(TestEntity t) {
em.merge(t);
}
public void remove(TestEntity t) {
em.remove(em.merge(t));
}
public void create(TestEntity t) {
em.persist(t);
}
#SuppressWarnings("unchecked")
public List<TestEntity> findAll() {
return em.createQuery("SELECT t FROM TestEntity t").getResultList();
}
}
Class TestBean:
#Named(value="testBean")
#Dependent
public class TestBean {
#EJB
private TestManager testManager;
/** Creates a new instance of TestBean */
public TestBean() {
}
public List<TestEntity> getEntities() {
return this.testManager.findAll();
}
}
I'm calling the TestBean.getEntities method:
...
<h:dataTable value="#{testBean.entities}" var="entity">
...
This causes the following exception:
javax.ejb.EJBException
at com.sun.ejb.containers.BaseContainer.processSystemException(BaseContainer.java:5119)
at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:5017)
at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4805)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2004)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1955)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:198)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:84)
at $Proxy141.findAll(Unknown Source)
at cz.vutbr.fit.pis.spravaTechniky.service.__EJB31_Generated__TestManager__Intf____Bean__.findAll(Unknown Source)
at cz.vutbr.fit.pis.spravaTechniky.back.TestBean.getEntities(TestBean.java:27)
...
I tried to replace the #PersistenceContext with #EJB, but got javax.ejb.EJBException: javax.ejb.CreateException: Could not create stateless EJB.

try to use this one
#EJB
EntityManager em;
em.persist(someobject);
instead of factory, if you need to use factory , i suggest you to repeat steps of setting up the persistance of entities in your IDE

Several things to correct here:
First, you are mixing Hibernate and EclipseLink in the same application (why??) you should just use one of them, choose between Hibernate or EclipseLink as both are implementations of the same standard: JPA (and you will need to choose the JPA API from one of those implementations).
Try to replace the #EJB annotation for a #Inject one. With the stack you are using that one should work.
Using the "dependent pseudo-scope" (by means of the #Dependent annotation) is the same as not establishing a scope at all (no annotation). Remove the #Dependent annotation from your bean class and place there a #RequestScoped (#SessionScoped, #ApplicationScoped or whatever scope your bean should have).

In the end I made JPA work just by using one of the example projects in NetBeans (File > New Project > Samples > Java Web > JSF JPA). I used this as a base for my project. I am not sure what I was doing wrong but at least everything worked fine then. Anyway, thanks for the help!

Related

Java EE - Connect EJB to Oracle Database through Glassfish resource

I am total newbie in Java and EE especially. I started an EE project that should provide REST API which will handle 2 entities in remote Oracle Database. I am using NetBeans because it is the only way how to accomplish anything in Enterprise Java (as I see it now).
What I've done:
I created JDBC pool in Glassfish (v4.1-13). I can ping the pool successfully. Then I created JDBC Resource for the pool.
I generated Entity classes for the two entities I need to handle.
<persistence version="2.1" xmlns...>
<persistence-unit name="semestralka-ejbPU" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/dbs</jta-data-source>
<class>cz.ctu.bitjv.kopecj24.semestralka.entities.Food</class>
<class>cz.ctu.bitjv.kopecj24.semestralka.entities.User</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="eclipselink.target-database" value="Oracle"/>
</properties>
</persistence-unit>
</persistence>
I have a stateless EJB which calls entity manager like this:
public FoodServiceBean()
{
this.facade = new FoodFacade(Food.class);
this.facade.setEntityManager(Persistence.createEntityManagerFactory("semestralka-ejbPU").createEntityManager());
}
Then, there is a REST service class that should list the entities from the database.
#Path("food")
public class FoodResource {
#Context
private UriInfo context;
private FoodServiceInterface service;
/**
* Creates a new instance of FoodResource
*/
public FoodResource() {
try {
InitialContext ic = new InitialContext();
service = (FoodServiceInterface) ic.lookup("java:global/semestralka/semestralka-ejb/FoodServiceBean");
} catch (NamingException ex) {...}
}
#GET
#Produces(MediaType.TEXT_PLAIN)
#Path("list")
public String getAll() {
List<Food> foods = service.listAllFood();
...
}
}
Unfortunately, once I request the getAll action (visit localhost:8080/semestralka-war/wr/food/list ) I get this exception:
Warning: StandardWrapperValve[cz.ctu.bitjv.kopecj24.semestralka.rest.ApplicationConfig]: Servlet.service() for servlet cz.ctu.bitjv.kopecj24.semestralka.rest.ApplicationConfig threw exception
javax.naming.NameNotFoundException: dbs not found
Here is a screenshot of the exception screen:
Double check the connection pool name in persistence unit and glassfish server. Also could you update your question with the entities.
I can see that your ejb calling from rest service is wrong. You need to add remote interface name with package path.
Lets say your package path is com.rs.www then your lookup string should be following one :
service = (FoodServiceInterface) ic.lookup("java:global/semestralka/semestralka-ejb/FoodServiceBean!com.rs.www.FoodServiceInterface");
Thanks.
Finally, I've found a solution. Problem was in my FoodServiceBean. I was trying to instantiate the facade in the EJB constructor but the EntityManager is injected after the constructor. So here is code of the Bean that helped me solve the issue.
#Stateless
#EJB(beanInterface=FoodServiceInterface.class, name="FoodServiceBean")
public class FoodServiceBean implements FoodServiceInterface {
#PersistenceContext(unitName="testPU")
private EntityManager em;
private FoodFacade facade;
public FoodServiceBean()
{
}
#PostConstruct
public void init() {
this.facade = new FoodFacade(Food.class);
this.facade.setEntityManager(em);
}
Please note that I changed the name of persistence unit just to be sure there are no typos.
Thanks for the help.

How to execute insert query on deploy of java ee application?

I have a java ee application with a web application and ejb module. There is some tables I want to be populated automatically when deployed. I have the entities set up and the sql file with the queries to be executed.
I feel it may be something to do with the persistence.xml file but not sure what to include. So, how do I get my server(wildfly) to execute the sql queries on deploy, similar to the way that you can specify the persistence.xml to drop and create as the table generation strategy.
If it makes a difference, I am using postgres for my database provider, java ee 7 and wildfly 8.2.0.Final for my server.
The solution I was looking for was like this, it belongs in the persistence.xml properties section.
<property name="javax.persistence.sql-load-script-source" value="META-INF/sql/data.sql" />
Database Schema Creation This link is useful for such techniques.
You could write a class extends from ServletContextListener which calls your method from the contextInitialized() method. You attach the listener to your webapp in web.xml, e.g.
<listener>
<listener-class>com.packages.Listener</listener-class>
</listener>
ServletListener code:
package com.packages;
public class Listener implements javax.servlet.ServletContextListener {
#Override
public void contextInitialized(ServletContext context) {
...
}
}
You can use Spring JDBC DataSource initializer feature or Instead of configuring DataSourceInitializer, you can use spring’s custom element jdbc:initialize-database element where jdbcnamespace xmlns:jdbc is set to http://www.springframework.org/schema/jdbc. You just need to point attribute data-source to the DataSource bean and configure the scripts using the child element jdbc:script and location attribute. For example, we can achieve the same result using the below configuration:
<jdbc:initialize-database data-source="dataSource" enabled="true">
<jdbc:script location="classpath:db-schema.sql" />
<jdbc:script location="classpath:db-load-data.sql" />
</jdbc:initialize-database>
At the very least you could use a servlet ContextListener to populate the database upon context start.
http://docs.oracle.com/javaee/7/api/javax/servlet/ServletContextListener.html
I've done such a trick for prototype applications in the past; just make sure to check if data doesn't already exist to prevent populating the database with duplicate data upon redeployments.
A rough example:
#WebListener
public class MyContextListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent sce){
// create manually, inject, whatever you're using
EntityManager em = ...;
Number cnt = (Number) em.createQuery("select count(d) from Data d").getSingleResult();
if(cnt.intValue() == 0){
insertFixtureData(em);
}
}
public void contextDestroyed(ServletContextEvent sce){
}
private void insertFixtureData(EntityManager em){
// insert data
}
}

java.lang.ClassCastException,Getting Entitymanager Via JNDI Lookup

I am new to JPA and developing a webapp(J2EE) where the webapp is in Tomcat so I can't use #PersistenceContext. I decided to use a Helper class and everything was going fine. Then I decided to implement JNDI for connection pooling and I managed to get Datasource.
The Helper Class looks like the following:
try {
Context initCtx = new InitialContext();
entityManager = //class cast exception
(EntityManager)initCtx.lookup(
"java:/comp/env/jdbc/LCDS"
);
DataSource ds= (DataSource)initCtx.lookup(
"java:/comp/env/jdbc/LCDS"
);
System.out.println(ds.getConnection()+"Cool");
//jdbc:mysql://localhost:3306/XXXXXXX, UserName=root#localhost, MySQL-AB JDBC DriverCool
emf=(EntityManagerFactory) source.getConnection(); //class cast exception
emf = Persistence.createEntityManagerFactory("XXXX"); //working version
}
The error is:
ava.lang.ClassCastException: org.apache.tomcat.dbcp.dbcp.BasicDataSource cannot be cast to javax.persistence.EntityManager
I don't know where I am getting wrong. I am not able to get EntityManagerFactory or EntityManager via JNDI lookup. I tried #Resource(name="jdbc/LCDS") and #PersistenceUnit(name="jdbc/LCDS").
To use a JNDI datasource in JPA, this should be specified in the persistence.xml, something like:
<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">
<persistence-unit name="..." transaction-type="RESOURCE_LOCAL">
<non-jta-data-source>java:/comp/env/jdbc/LCDS</non-jta-data-source>
...
Then you just have to create your EntityManagerFactory via Persistence#createEntityManagerFactory(String). If you want to recycle the EntityManagerFactory, this should be done outside of JNDI (e.g. as a ServletContext attribute). This is because Tomcat is not a Java EE server, only a servlet container: he is not able to inject the persistence unit.
UPDATE
JNDI access to persistence unit is not possible due to Tomcat limitations. See JPA Tomcat limitations. You will have to use emf = Persistence.createEntityManagerFactory("UNIT NAME").
Sorry for misleading answer. I've tested that on WebSphere Liberty, didn't have Tomcat at hand.
If you need that functionality check WebSphere Liberty, which is as fast and lightweight as Tomcat, but is fully Java EE Web profile compliant. It has lots of useful features like JPA, EJBLite, JAX-RS already available if needed, without fighting with additional libraries configuration.
UPDATE END
I've checked on WebSphere Liberty, you need to create reference to lookup your persistence unit via JNDI. You have two options to create that:
Use annotation at the class level
In any of your servlets you need to define annotation using the follownig:
#PersistenceUnit(name="JPATestRef", unitName="UnitName")
public class JPATester extends HttpServlet {
...
Use entry in web.xml
<persistence-unit-ref>
<persistence-unit-ref-name>JPATestRef</persistence-unit-ref-name>
<persistence-unit-name>UnitName</persistence-unit-name>
</persistence-unit-ref>
Then you access it using the following code:
try {
InitialContext ctx = new InitialContext();
System.out.println("looking EntityManagerFactory:");
EntityManagerFactory emf2 = (EntityManagerFactory) ctx.lookup("java:comp/env/JPATestRef");
System.out.println("emf:2" + emf2);
} catch (NamingException e) {

joinTransaction has been called on a resource-local EntityManager in JBoss

I have earlier worked with application-managed RESOURCE-LOCAL transaction but now I want to use container-managed JTA transaction. Everything seems to be ok while I am using #Stateless but as soon as I use #Stateful I get an exception as below
javax.ejb.EJBException: javax.persistence.TransactionRequiredException: joinTransaction has been called on a resource-local EntityManager which is unable to register for a JTA transaction.
I am using JBoss eap 6.2 with eclipselink2.5 and Java8 and Oracle.Here are my codes
#Stateful
#TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class LoginDetailService {
#PersistenceContext(unitName="OracleDB", type=PersistenceContextType.EXTENDED)
protected EntityManager em;
public void addLoginDetails(String email, String pwd){
LoginDetail ld = new LoginDetail(email,pwd);
em.persist(ld);
}
#Remove
public void finished(){}
}
My Servlet code
#WebServlet("/signup")
public class SignUpServlet extends HttpServlet {
#EJB LoginDetailService bean;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String email = "EMAIL",
pwd = "PASSWORD";
bean.addLoginDetails(email, pwd); //exception occurs here
response.getWriter().println("Successful");
}
}
And my persistence.xml file
<?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="OracleDB" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>java:jboss/jdbc/OracleDB</jta-data-source>
<class>com.entity.Student</class>
<class>com.entity.LoginDetail</class>
<properties>
<property name="eclipselink.logging.level" value="FINEST"/>
</properties>
</persistence-unit>
</persistence>
Plz hekp and guide me where I am going wrong. Thanks
Finally after working a lot, I found the problem. Actually there was no issue with my code, it was because of the JBoss server. I tested the same application with Glassfish4 and it worked perfectly.
REASON
The annotation #EJB has no effect in JBoss. Though you will see that a JNDI binding has occurred with the bean but when you will try tp persist, it wont work.
SOLUTION
To make it work on JBoss instead of #EJB, you will have to do a JNDI lookup and carry out the transaction. But the lookup for some reason failed on my desktop but worked fine on laptop may be due to some weird server configuration.
Another and better solution which I feel is to use another server like Glassfish or WebLogic where #EJB works fine and not a single bit of extra coding.

Correct usage of JPA in jsp application

I'm trying to develop a simple JSP based web application with JPA and would like to know the correct usage for developing one.
In my sample application I have two JSP pages and a simple Java class to perform database operations. Both the JSP files use this Java class to perform DB operations.
I've annotated this class with #Stateless and injected an Entity manager as follows:
#PersistenceContext(unitName = "myjpa")
EntityManager em;
In my persistence.xml I've set the following property:
<property
name="hibernate.transaction.jta.platform"
value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform"
/>
I'm calling the class in JSP using JNDI (as the class is annotated for a stateless session bean) as follows:
InitialContext ic = new InitialContext();
Sample sample = (Sample) ic.lookup("java:app/" + application.getContextPath() + "/Sample");
I'm facing the following scenarios:
When I try to use a transaction em.getTransaction().begin()/commit() for insert and update, it says can not use transaction with JTA case.
So in the constructor code of my Java class I use the following code:
Properties properties = new Properties();
properties.put("javax.persistence.transactionType", "RESOURCE_LOCAL");
emf = Persistence.createEntityManagerFactory("myjpa",properties);
em = emf.createEntityManager();
I tried to use transactions like em.getTransaction().begin()/commit().
But in this case the pages become very slow after 2-3 database update and load operations. Though I'm not getting any exception. Overall in my table I'm having less than 25 records.
To me it seems as if it is waiting internally for some operation to complete.
At the same time I also feel that the way I'm using JPA is wrong and hence soliciting advice for the correct approach for doing even simple web apps with JSP and JPA.
While I'm still exploring Java EE, in case you have any specific reference for such cases I'll like to read and look them too.
You should always strive to use JTA transactions which means the container will handle the transaction demarcations. In your case if you want to handle transactions by your self, you need to define it as a bean managed transaction. So in your EJB class, after the #Stateless annoattions, you should define the following annotation;
#TransactionManagement(TransactionManagementType.BEAN)
The usual best practice is to let the container handle the transactions, unless there is some explicit reason for you to use Bean managed transactions.
At the same time I also feel that the way I'm using JPA is wrong
Your usage indeed seems wrong. If you're using a (stateless) session bean you do not have to fiddle with em.getTransaction().begin()/commit() and you definitely don't have to use code such as Persistence.createEntityManagerFactory.
You also don't have to set the property org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform.
A session bean automatically manages the transaction for you, and within a Java EE AS (such as JBoss AS) you don't have to configure any transaction manager or similar things.
An example:
#Stateless
public class UserDAO {
#PersistenceContext
private EntityManager entityManager;
public void add(User user) {
entityManager.persist(user);
}
}
As for the persistence.xml file, something like the following should be enough to get started:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.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_2_0.xsd">
<persistence-unit name="somePU">
<jta-data-source>java:app/someDS</jta-data-source>
</persistence-unit>
</persistence>
Some more examples:
http://jdevelopment.nl/sample-crud-app-with-jsf-and-richfaces
http://arjan-tijms.omnifaces.org/2011/08/minimal-3-tier-java-ee-app-without-any.html

Categories