You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@roller.apache.org by Denis Balazuc <de...@balazuc.net> on 2007/06/17 16:24:38 UTC
Troubles with JPA
Hi all
I'm having troubles running the current 4.0 trunk with JPA. I have a
NullPointerException that happens during JPAPersistenceStrategy
initialisation. Although I see where that comes from, I do not know how
to fix it. It's probably some configuration that I'm missing and you've
probably already seen this.
Here's the details (that's for Roller - I'm not trying to run Planet yet)
-- Opening the homepage on Roller, or any task trying to instantiate
Roller through the RollerFactory using JPA as the persistence layer,
produces this ->
java.lang.NullPointerException
at
org.apache.roller.weblogger.business.jpa.JPAPersistenceStrategy.getThreadLocalEntityManager(JPAPersistenceStrategy.java:273)
at
org.apache.roller.weblogger.business.jpa.JPAPersistenceStrategy.getEntityManager(JPAPersistenceStrategy.java:260)
at
org.apache.roller.weblogger.business.jpa.JPAPersistenceStrategy.getNamedQuery(JPAPersistenceStrategy.java:294)
at
org.apache.roller.weblogger.business.jpa.JPAPropertiesManagerImpl.getProperties(JPAPropertiesManagerImpl.java:87)
at
org.apache.roller.weblogger.business.jpa.JPAPropertiesManagerImpl.init(JPAPropertiesManagerImpl.java:130)
at
org.apache.roller.weblogger.business.jpa.JPAPropertiesManagerImpl.<init>(JPAPropertiesManagerImpl.java:65)
-- The real reason why the NPE happens is because in the constructors of
JPAPersistenceStrategy, the call
this.emf = Persistence.createEntityManagerFactory(puName, emfProperties);
returns an expected NULL value, which produces the NPE later when the
member variable "emf" is accessed.
Since the hibernate persistence layer works just fine, I am guessing
that I am missing some JPA configuration but can't really find what (I
know close to nothing about JPA) and there's nothing in the logs that
looks mighty wrong. I reckon I've digged deeper in the code than in the
documentation, but any further pointer (not null!) would help.
Thanks a lot
Denis Balazuc
PS
The following JPAPersistenceStrategy.java patch does NOT fix the issue
but avoids the NPE by providing a clearer error message in the Roller
log file when NULL is returned by
Persistence.createEntityManagerFactory(puName, emfProperties), then
throws an expected WebloggerException indicating the issue and
preventing further initialisation (rather than Roller bombing out later
with a NPE).
------------------------ PATCH -------------------------------------
Index:
apps/weblogger/src/java/org/apache/roller/weblogger/business/jpa/JPAPersistenceStrategy.java
===================================================================
---
apps/weblogger/src/java/org/apache/roller/weblogger/business/jpa/JPAPersistenceStrategy.java
(revision 547933)
+++
apps/weblogger/src/java/org/apache/roller/weblogger/business/jpa/JPAPersistenceStrategy.java
(working copy)
@@ -19,26 +19,29 @@
package org.apache.roller.weblogger.business.jpa;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.Collection;
-import java.util.Properties;
+import java.util.Enumeration;
import java.util.Iterator;
-import java.util.Enumeration;
import java.util.Properties;
-import java.io.InputStream;
-import java.io.IOException;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.roller.weblogger.WebloggerException;
+
+import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
-import javax.persistence.EntityManager;
import javax.persistence.FlushModeType;
import javax.persistence.Persistence;
import javax.persistence.PersistenceException;
import javax.persistence.Query;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.Validate;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.roller.weblogger.WebloggerException;
+
/**
* JPAPersistenceStrategy is responsible for the lowest-level
interaction with
* the JPA API.
@@ -70,29 +73,8 @@
String puName,
String jndiName,
Properties properties) throws WebloggerException {
-
- // set strategy used by Datamapper
- // You can configure JPA completely via the JPAEMF.properties file
- Properties emfProps = loadPropertiesFromResourceName(
- "JPAEMF.properties", getContextClassLoader());
-
- // Add additional properties passed in
- Enumeration keys = properties.keys();
- while (keys.hasMoreElements()) {
- String key = (String)keys.nextElement();
- String value = properties.getProperty(key);
- logger.info(key + ": " + value);
- emfProps.setProperty(key, value);
- }
-
- emfProps.setProperty("openjpa.ConnectionFactoryName", jndiName);
-
- try {
- this.emf = Persistence.createEntityManagerFactory(puName,
emfProps);
- } catch (PersistenceException pe) {
- logger.error("ERROR: creating entity manager", pe);
- throw new WebloggerException(pe);
- }
+ this(puName,
+ createJPAPersistenceStrategyProperties(jndiName, properties));
}
/**
@@ -106,49 +88,45 @@
String username,
String password,
Properties properties) throws WebloggerException {
-
- logger.info("driverClass: " + driverClass);
- logger.info("connectionURL: " + connectonUrl);
- logger.info("username: " + username);
-
- // set strategy used by Datamapper
- // You can configure JPA completely via the JPAEMF.properties file
- Properties emfProps = loadPropertiesFromResourceName(
- "JPAEMF.properties", getContextClassLoader());
-
- // Add additional properties passed in
- Enumeration keys = properties.keys();
- while (keys.hasMoreElements()) {
- String key = (String)keys.nextElement();
- String value = properties.getProperty(key);
- logger.info(key + ": " + value);
- emfProps.setProperty(key, value);
- }
-
- // Try to please all the players
- emfProps.setProperty("openjpa.ConnectionDriverName",
driverClass);
- emfProps.setProperty("openjpa.ConnectionURL",
connectonUrl);
- emfProps.setProperty("openjpa.ConnectionUserName", username);
- emfProps.setProperty("openjpa.ConnectionPassword",
password);
-
- emfProps.setProperty("toplink.jdbc.driver",
driverClass);
- emfProps.setProperty("toplink.jdbc.url",
connectonUrl);
- emfProps.setProperty("toplink.jdbc.user", username);
- emfProps.setProperty("toplink.jdbc.password", password);
-
-
emfProps.setProperty("hibernate.connection.driver_class",driverClass);
- emfProps.setProperty("hibernate.connection.url",
connectonUrl);
- emfProps.setProperty("hibernate.connection.username", username);
- emfProps.setProperty("hibernate.connection.password",
password);
-
- try {
- this.emf = Persistence.createEntityManagerFactory(puName,
emfProps);
- } catch (PersistenceException pe) {
- logger.error("ERROR: creating entity manager", pe);
- throw new WebloggerException(pe);
- }
+ this(puName, createJPAPersistenceStrategyProperties(
+ driverClass,
+ connectonUrl,
+ username,
+ password,
+ properties));
}
-
+
+ protected JPAPersistenceStrategy(String puName, Properties
emfProperties) throws WebloggerException {
+ super();
+ Validate.isTrue(
+ StringUtils.isNotBlank(puName),
+ "Null or blank puName parameter.");
+ Validate.notNull(
+ emfProperties,
+ "Null or blank EMF properties parameter.");
+
+ try {
+ this.emf = Persistence.createEntityManagerFactory(puName,
emfProperties);
+ if (null == emf) {
+ logger.error(
+ "ERROR: unable to create an EntityManagerFactory. " +
+ "Persistence.createEntityManagerFactory returned a NULL
value. " +
+ "The current property set is probably incorrect for the
persistence unit '" + puName + "'.");
+ if (logger.isDebugEnabled()) {
+ logger.debug(
+ "Persistence.createEntityManagerFactory properties
for puName '" +
+ puName + "' (JPAEMF.properties):\n" +
+ emfProperties.toString());
+ }
+ throw new WebloggerException("ERROR: unable to create an
EntityManagerFactory.");
+ }
+ } catch (PersistenceException pe) {
+ logger.error("ERROR: creating entity manager", pe);
+ throw new WebloggerException(pe);
+ }
+ }
+
+
/**
* Flush changes to the datastore, commit transaction, release em.
* @throws org.apache.roller.WebloggerException on any error
@@ -325,6 +303,73 @@
return q;
}
+ private static Properties createJPAPersistenceStrategyProperties(
+ String jndiName,
+ Properties properties) throws WebloggerException {
+
+ // set strategy used by Datamapper
+ // You can configure JPA completely via the JPAEMF.properties file
+ Properties emfProps = loadPropertiesFromResourceName(
+ "JPAEMF.properties", getContextClassLoader());
+
+ // Add additional properties passed in
+ Enumeration keys = properties.keys();
+ while (keys.hasMoreElements()) {
+ String key = (String)keys.nextElement();
+ String value = properties.getProperty(key);
+ logger.info(key + ": " + value);
+ emfProps.setProperty(key, value);
+ }
+
+ emfProps.setProperty("openjpa.ConnectionFactoryName", jndiName);
+ return emfProps;
+ }
+
+ public static Properties createJPAPersistenceStrategyProperties(
+ String driverClass,
+ String connectonUrl,
+ String username,
+ String password,
+ Properties properties) throws WebloggerException {
+
+ logger.info("driverClass: " + driverClass);
+ logger.info("connectionURL: " + connectonUrl);
+ logger.info("username: " + username);
+
+ // set strategy used by Datamapper
+ // You can configure JPA completely via the JPAEMF.properties file
+ Properties emfProps = loadPropertiesFromResourceName(
+ "JPAEMF.properties", getContextClassLoader());
+
+ // Add additional properties passed in
+ Enumeration keys = properties.keys();
+ while (keys.hasMoreElements()) {
+ String key = (String)keys.nextElement();
+ String value = properties.getProperty(key);
+ logger.info(key + ": " + value);
+ emfProps.setProperty(key, value);
+ }
+
+ // Try to please all the players
+ emfProps.setProperty("openjpa.ConnectionDriverName",
driverClass);
+ emfProps.setProperty("openjpa.ConnectionURL",
connectonUrl);
+ emfProps.setProperty("openjpa.ConnectionUserName", username);
+ emfProps.setProperty("openjpa.ConnectionPassword",
password);
+
+ emfProps.setProperty("toplink.jdbc.driver",
driverClass);
+ emfProps.setProperty("toplink.jdbc.url",
connectonUrl);
+ emfProps.setProperty("toplink.jdbc.user", username);
+ emfProps.setProperty("toplink.jdbc.password", password);
+
+
emfProps.setProperty("hibernate.connection.driver_class",driverClass);
+ emfProps.setProperty("hibernate.connection.url",
connectonUrl);
+ emfProps.setProperty("hibernate.connection.username", username);
+ emfProps.setProperty("hibernate.connection.password",
password);
+
+ return emfProps;
+ }
+
+
/**
* Loads properties from given resourceName using given class loader
* @param resourceName The name of the resource containing properties
Re: Troubles with JPA
Posted by Denis Balazuc <de...@balazuc.net>.
I have finally nailed it down. It came from a misconfiguration of my
JNDI datasource (which basically had no config at all, starting with no
connection URL....). This produces a lot of other NPEs in various places
in Roller along the line.
It is interesting to see that in this case, the JPA implementation used
apparently doesn't really honor its API doc since an exception was
expected in the case of a misconfiguration rather than returning a null
value from its factory (see my patch, which error message isn't really
helping).
Regards
Denis
Dave wrote:
> On 6/17/07, Denis Balazuc <de...@balazuc.net> wrote:
>> I'm having troubles running the current 4.0 trunk with JPA. I have a
>> NullPointerException that happens during JPAPersistenceStrategy
>> initialisation. Although I see where that comes from, I do not know how
>> to fix it. It's probably some configuration that I'm missing and you've
>> probably already seen this.
>
> Denis,
>
> I haven't seen that particular error before.
>
> On a related note. I just deployed the latest code from the trunk to
> rollerweblogger.org and I'm using the JPA backend, everything seem to
> be working fine.
>
> - Dave
>
Re: Troubles with JPA
Posted by Dave <sn...@gmail.com>.
On 6/17/07, Denis Balazuc <de...@balazuc.net> wrote:
> I'm having troubles running the current 4.0 trunk with JPA. I have a
> NullPointerException that happens during JPAPersistenceStrategy
> initialisation. Although I see where that comes from, I do not know how
> to fix it. It's probably some configuration that I'm missing and you've
> probably already seen this.
Denis,
I haven't seen that particular error before.
On a related note. I just deployed the latest code from the trunk to
rollerweblogger.org and I'm using the JPA backend, everything seem to
be working fine.
- Dave