问题
Using the Google Eclipse Plugin, my project automatically comes with two files inside the META-INF folder: jdoconfig.xml
and persistence.xml
. Per the instructions on https://developers.google.com/appengine/docs/java/datastore/jpa/overview, my persistence file is supposed to have the following line for jpa datastore storage:
<provider>org.datanucleus.store.appengine.jpa.DatastorePersistenceProvider</provider>
But when I open the persistence file I found
<?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="transactions-optional">
<provider>org.datanucleus.api.jpa.PersistenceProviderImpl</provider>
<properties>
<property name="datanucleus.NontransactionalRead" value="true"/>
<property name="datanucleus.NontransactionalWrite" value="true"/>
<property name="datanucleus.ConnectionURL" value="appengine"/>
</properties>
</persistence-unit>
</persistence>
and the jdoconfig.xml
file is
<?xml version="1.0" encoding="utf-8"?>
<jdoconfig xmlns="http://java.sun.com/xml/ns/jdo/jdoconfig"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://java.sun.com/xml/ns/jdo/jdoconfig">
<persistence-manager-factory name="transactions-optional">
<property name="javax.jdo.PersistenceManagerFactoryClass"
value="org.datanucleus.store.appengine.jdo.DatastoreJDOPersistenceManagerFactory"/>
<property name="javax.jdo.option.ConnectionURL" value="appengine"/>
<property name="javax.jdo.option.NontransactionalRead" value="true"/>
<property name="javax.jdo.option.NontransactionalWrite" value="true"/>
<property name="javax.jdo.option.RetainValues" value="true"/>
<property name="datanucleus.appengine.autoCreateDatastoreTxns" value="true"/>
</persistence-manager-factory>
</jdoconfig>
With those default contents, JPA has not been saving to my datastore. So I edit the persistence.xml
file to look like this
<?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="transactions-optional">
<provider>org.datanucleus.store.appengine.jpa.DatastorePersistenceProvider</provider>
<properties>
<property name="datanucleus.NontransactionalRead" value="true"/>
<property name="datanucleus.NontransactionalWrite" value="true"/>
<property name="datanucleus.ConnectionURL" value="appengine"/>
</properties>
</persistence-unit>
</persistence>
How should I change the jdoconfig.xml
file? Right now, with my changes to persistence
but jdoconfig
as is, I am getting a huge error trace.
redacted error:
java.lang.ExceptionInInitializerError
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:169)
at com.google.appengine.tools.development.agent.runtime.RuntimeHelper.checkRestricted(RuntimeHelper.java:70)
at com.google.appengine.tools.development.agent.runtime.Runtime.checkRestricted(Runtime.java:64)
…
…
...
Caused by: javax.persistence.PersistenceException: No persistence providers available for "transactions-optional" after trying the following discovered implementations: org.datanucleus.api.jpa.PersistenceProviderImpl
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:180)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:70)
回答1:
For JPA 2.0 The provider is org.datanucleus.api.jpa.PersistenceProviderImpl
Please note that persistence.xml
is the configuration file used by JPA and jdoconfig.xml
is used if you want to use JDO.
You first need to decide what persistence mechanism you want to use, I would assume its JPA so in fact, you can delete jdoconfig.xml
.
With that been said, make sure all the reguired libs for Datanucleus is in your CLASSPATH and most importantly, persisence.xml must be in the ROOT of your CLASSPATH.
I have added a picture of the lib needed for a successful JPA 2 / Datanucleus persitence.
Also make sure your enhancer is correctly configured.
FYI: I could never get Google Eclipse Plugin to work with JPA 2, the entity enhancements never worked so I used maven. There are several ways to enhance your classes and maven is one.
Here is my pom.
<properties>
<!-- Convenience property to set the GWT version -->
<gwtVersion>2.5.0</gwtVersion>
<gxtVersion>2.2.5</gxtVersion>
<gae.version>1.7.5</gae.version>
<datanucleus.version>3.1.3</datanucleus.version>
<!-- GWT needs at least java 1.5 -->
<webappDirectory>${project.build.directory}/${project.build.finalName}</webappDirectory>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!-- DN -->
<dependency>
<groupId>com.google.appengine.orm</groupId>
<artifactId>datanucleus-appengine</artifactId>
<version>2.1.2</version>
</dependency>
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-core</artifactId>
<version>${datanucleus.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-api-jpa</artifactId>
<version>${datanucleus.version}</version>
</dependency>
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-api-jdo</artifactId>
<version>${datanucleus.version}</version>
</dependency>
<dependency>
<groupId>javax.jdo</groupId>
<artifactId>jdo-api</artifactId>
<version>3.0.1 </version>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jpa_2.0_spec</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-jsr107cache</artifactId>
<version>${gae.version}</version>
</dependency>
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-endpoints</artifactId>
<version>${gae.version}</version>
</dependency>
<dependency>
<groupId>net.sf.jsr107cache</groupId>
<artifactId>jsr107cache</artifactId>
<version>1.1</version>
</dependency>
For the enhancements, add the following to plugins section of your pom:
<plugin>
<groupId>org.datanucleus</groupId>
<artifactId>maven-datanucleus-plugin</artifactId>
<version>${datanucleus.version}</version>
<configuration>
<api>JPA</api>
<verbose>true</verbose>
<mappingIncludes>**/entity/*.class</mappingIncludes>
<fork>false</fork>
<log4jConfiguration>${basedir}/log4j.properties</log4jConfiguration>
</configuration>
<executions>
<execution>
<phase>process-classes</phase>
<goals>
<goal>enhance</goal>
</goals>
</execution>
</executions>
</plugin>
Change <mappingIncludes>**/entity/*.class</mappingIncludes>
to the package where your entities are placed.
In my own case, DataNucleus Enhancer will look for classes to enhance in package/folder named entity
.
Good luck
Babajide
来源:https://stackoverflow.com/questions/15821716/how-to-edit-jdoconfig-xml-and-persistence-xml-so-jpa-saves-to-appengine-datastor