I am learning J2EE recently.
I use IntelliJ, and my web server is Tomcat. I want to add OpenJPA to my project, but I meet some problems.
I have two entities: BooksEntity and SourcesEntity.
When I called createEntityManager() in the Servlet, it gave me a NullPointerException.
It seems that I missed something, but I don't know why.
Here is the exception information:
java.lang.NullPointerException
controller.TestServlet.doGet(TestServlet.java:28)
javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
This is my TestServlet.java file:
#WebServlet(name = "TestServlet", urlPatterns = {"/books"})
public class TestServlet extends HttpServlet {
#PersistenceUnit (unitName = "booksPU")
private EntityManagerFactory emf;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
EntityManager em = emf.createEntityManager();
Query query = em.createNamedQuery("Books.findAll");
request.setAttribute("books", (List<BooksEntity>) query.getResultList());
request.getRequestDispatcher("index.jsp").forward(request, response);
}
}
The exception was thrown in this line: EntityManager em = emf.createEntityManager();
This is my context.xml file:
<Context>
<Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="10000"
username="root" password="******" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/FIRST_TEST"/>
</Context>
My persistence.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="booksPU">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<class>model.BooksEntity</class>
<class>model.SourcesEntity</class>
<properties>
<property name="openjpa.ConnectionURL" value="jdbc:mysql://localhost:3306/FIRST_TEST"/>
<property name="openjpa.ConnectionDriverName" value="com.mysql.jdbc.Driver"/>
<property name="openjpa.ConnectionUserName" value="root"/>
<property name="openjpa.ConnectionPassword" value="******"/>
</properties>
</persistence-unit>
</persistence>
========2014.06.06========
My directory structure:
========2014.06.07========
This is probably just a typo in your code. The annotation should be #PersistenceContext, not #PersistentUnit. This is why emf remains null.
Make sure that when you package your war file the persistence.xml is located in WEB-INF/classes/META-INF folder.
Related
I am using JEE5 with Postgresql, When I try to persist the object the output says
Could not find datasource: java:jdbc/postgres
javax.naming.NameNotFoundException: the name jdbc/postgres is not
asociated with this context
In context.xml (Tomcat7) I have
<Context>
<Resource name="jdbc/postgres" auth="Container"
type="javax.sql.DataSource" driverClassName="org.postgresql.Driver"
url="jdbc:postgresql://127.0.0.1:5433/peopledb"
username="postgres" password="password" maxActive="20" maxIdle="10"
maxWait="-1"/>
</Context>
In persistence.xml I have:
<persistence-unit name="People">
<jta-data-source>java:jdbc/postgres</jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.show_sql" value="true" />
</properties>
</persistence-unit>
In my persistence bean I have
#Stateless
public class PeopleDAOImpl implements PeopleDAO {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("People");
#Override
public void persistPeople(People pep) {
EntityManager em = emf.createEntityManager();
em.persist(pep);
}
}
Tomcat names the context resources differently than Glassfish. You defined the name in context.xml as jdbc/postgres, but in the persistence.xml you have to use java:comp/env/jdbc/postgres.
A late reply, but maybe still useful for others:
JTA can be used in Tomcat with componentized implementations like Atomikos (https://www.atomikos.com).
Cheers
PS: if you want help in setting things up you may want to consider a free trial of Atomikos - which includes Tomcat support / setup.
This is essentially a duplicate of How to locate the source of JBAS011470 error in JBoss?
But essentially, As soon as I add a second persistence unit, it gives me this error. It's ridiculous. I'm not going to disable the JPA subsystem like some people suggest - that sounds wrong.
My persistence.xml setup is as follows, where java:/NAME is set up as a datasource in standalone.xml:
<?xml version="1.0"?>
<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="name" transaction-type="JTA">
<jta-data-source>java:/NAME</jta-data-source>
<class>za.co.classes.A</class>
<class>za.co.classes.B</class>
<class>za.co.classes.C</class>
<properties>
<property name="hibernate.transaction.jta.platform"
value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform"/>
<property name="hibernate.transaction.manager_lookup_class"
value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
<property name="jboss.entity.manager.factory.jndi.name"
value="java:jboss/persistence/NAME" />
<property name="jboss.entity.manager.jndi.name"
value="java:jboss/persistence/em/NAME" />
<property name="hibernate.dialect" value="za.co.equrahealth.dao.SQLServerDialect" />
</properties>
</persistence-unit>
The error starts as soon as I add a second persistence unit. So spring context is irrelevant.
Well, I luckily have multiple databases within the same schema, so I came up with a workaround. But it's obviously not going to solve the problem when there are multiple schemas. I think the cause of this issue might actually be a bug in JBoss.
#PersistenceContext
private EntityManager entityManager;
private EntityManager getEntityManager(String source)
{
if ("a".equalsIgnoreCase(source))
{
entityManager.createNativeQuery("USE A_DB;").executeUpdate();
}
else
{
entityManager.createNativeQuery("USE B_DB").executeUpdate();
}
return entityManager;
}
I am getting following exception in tomee deployed application.
[EL Severe]: 2014-07-11 09:18:34.811--ServerSession(860687693)--Thread(Thread[http-bio-8081-exec-3,5,main])--Local Exception Stack:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: Driver:org.hsqldb.jdbcDriver#7078c2bb returned null for URL:"jdbc:mysql://localhost:3306/testDB"
Error Code: 0
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:316)
at org.eclipse.persistence.sessions.JNDIConnector.connect(JNDIConnector.java:135)
at org.eclipse.persistence.sessions.DatasourceLogin.connectToDatasource(DatasourceLogin.java:162)
at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.setOrDetectDatasource(DatabaseSessionImpl.java:204)
at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:741)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:239)
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:685)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.getAbstractSession(EntityManagerFactoryDelegate.java:204)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.createEntityManagerImpl(EntityManagerFactoryDelegate.java:304)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:336)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:309)
at org.apache.openejb.assembler.classic.ReloadableEntityManagerFactory.createEntityManager(ReloadableEntityManagerFactory.java:159)
at org.apache.openejb.persistence.JtaEntityManagerRegistry.getEntityManager(JtaEntityManagerRegistry.java:115)
at org.apache.openejb.persistence.JtaEntityManager.getEntityManager(JtaEntityManager.java:91)
at org.apache.openejb.persistence.JtaEntityManager.find(JtaEntityManager.java:164)
heres my tomee.xml file,
<tomee>
<Resource id="testDBPool" type="DataSource">
jdbcDriverClassName = "com.mysql.jdbc.Driver"
url = "jdbc:mysql://localhost:3306/testDB"
username = "admin"
password = "admin"
</Resource>
</tomee>
I already put mysql_connector jar in my tomee/lib folder.
My persistence.xml file as below,
<?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="TestPersistence"
transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/testDBPool</jta-data-source>
<shared-cache-mode>NONE</shared-cache-mode>
<properties>
<property name="eclipselink.weaving" value="static" />
<property name="eclipselink.logging.level.sql" value="FINEST" />
<property name="eclipselink.logging.level" value="FINEST" />
<property name="eclipselink.logging.level.cache" value="FINEST" />
</properties>
</persistence-unit>
</persistence>
I do not understand where I am wrong, why I am getting this exception?
Please help me to solve this.
The problem is that you are using the wrong property name to declare the JDBC driver. According to Apache TomEE: DataSource Configuration, the property for the driver name is jdbcDriver, and not jdbcDriverClassName. The default value for jdbcDriver is org.hsqldb.jdbcDriver. So as I commented earlier it will try to create a connection using HSQLDB, but with a MySQL JDBC url.
To fix your problem change your configuration to:
<tomee>
<Resource id="testDBPool" type="DataSource">
jdbcDriver = "com.mysql.jdbc.Driver"
...
</Resource>
</tomee>
I am doing web application.I found many questions with same problem
Like this question
But I didn't get correct answer. My folder structure and class path everything is correct but why this Exception occurring really I don't know.
Below is my folder structure. Here persistence.xml file is within META-INF folder of src folder
My Persistance.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_1_0.xsd"
version="1.0">
<persistence-unit name="jspWithJpa" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.entity.Student</class>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/reports" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="root" />
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
</properties>
</persistence-unit>
</persistence>
EntityManagerUtil
public class EntityManagerUtil {
private static final EntityManagerFactory emf;
static {
try {
emf = Persistence.createEntityManagerFactory("jspWithJpa");
}
catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static EntityManagerFactory getEmf() {
return emf;
}
}
Exception Is:
Initial SessionFactory creation failed.javax.persistence.PersistenceException: No Persistence provider for EntityManager named jspWithJpa
Mar 2, 2014 11:16:08 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [com.action.InsertData] in context with path [/jspWithJpa] threw exception [Servlet execution threw an exception] with root cause
javax.persistence.PersistenceException: No Persistence provider for EntityManager named jspWithJpa
Change your provider tag to in persistence.xml to:
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
from your libs i can see that you're using eclipselink as JPA provider, not hibernate.
I have been learning about how to set up Tomcat's connection pool through this website. So I made a context.xml file and put it in the directory META-INF. This is what I have right now.
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource name="jdbc/gmustudent" auth="Container"
type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver"
username="root" password="root"
url="jdbc:mysql://localhost:3306/official"
maxActive="100" maxIdle="10" minIdle="5" initialSize="5" maxWait="10000" />
</Context>
However I would like to specify the class name of the factory. But everytime I add this attribute
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
I get a huge pile of errors in my console. Here are some of them in no particular order.
WARNING: Failed to register in JMX: javax.naming.NamingException: com.mysql.jdbc.Driver
WARNING: Unexpected exception resolving reference java.sql.SQLException: com.mysql.jdbc.Driver
WARNING: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.jee.server:gmustudent' did not find a matching property.
So when I do not specify a factory the site works just fine. But when I do errors are thrown and nothing works. I did some research on stack overflow and found this post. Because of this I changed my tomcat version from 7.0.11 to the most recent but am still getting the error. So then I thought maybe it is some kind of clash with my factory in my server.xml file but I am not nearly experienced to make that call. But here is the resource in my server.xml file
<Resource auth="Container" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase" pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase"/>
So is this clashing with the factory in my context.xml file? Or am I totally wrong here? In a nut shell I would like to find out how to specify a factory in my context.xml file without getting a huge error. Thank you for reading.
You can actually manage the entire connection in your web app using Spring if you want. Here is an example using PostgreSQL:
<?xml version="1.0" encoding="windows-1252"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="myDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.postgresql.Driver"/>
<property name="url" value="jdbc:postgresql://localhost/mydb"/>
<property name="username" value="postgres"/>
<property name="password" value="postgres"/>
</bean>
</beans>
You can just put that in WEB-INF/classes and load it using:
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/mycontext.xml");
I wouldn't even bother with having Tomcat manage it at this point.