我在使用DataNucleus作爲Glassfish AS上的ORM框架時遇到了麻煩。其實我試圖用來連接到MongoDb。因爲大家都知道nosql數據庫不是標準的一部分,但我期望遇到問題,但我面臨使用DataNucleus的問題。這是我沒有想到的。我對DataNucleus和MongoDB都不熟悉,不幸的是我沒有在WEB上找到任何相關的信息,所以我決定一步步地進行。使用DataNucleus和Glassfish 3.x
我創建了一個使用DataNucleus和MongoDB並使用Maven構建的小型命令行應用程序。相關代碼如下
persistece.xml
<?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="just_test">
<provider>org.datanucleus.api.jpa.PersistenceProviderImpl</provider>
<properties>
<property name="datanucleus.ConnectionURL" value="mongodb:/justtest"/>
<property name="datanucleus.autoCreateSchema" value="true"/>
<property name="datanucleus.validateTables" value="false"/>
<property name="datanucleus.validateConstraints" value="false"/>
</properties>
</persistence-unit>
</persistence>
代碼爲持續的實體
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
public class App {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("just_test");
// Create entity manager
EntityManager em = null;
String id;
try {
em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
TestEntity testEntity = new TestEntity();
tx.begin();
em.persist(testEntity);
em.flush();
tx.commit();
id = testEntity.getId();
} finally {
if (null != em) {
em.close();
}
}
try {
em = emf.createEntityManager();
TestEntity testEntity = em.find(TestEntity.class, id);
System.out.println(testEntity);
} finally {
if (null != em) {
em.close();
}
}
}
的pom.xml
...
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>[2.9.3,)</version>
<!--<scope>provided</scope>-->
</dependency>
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-core</artifactId>
<version>[2.9,)</version>
</dependency>
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-mongodb</artifactId>
<version>[2.9,)</version>
</dependency>
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-api-jpa</artifactId>
<version>[3.0,)</version>
</dependency>
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-api-jdo</artifactId>
<version>[3.0,)</version>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jpa_2.0_spec</artifactId>
<version>[1.0,)</version>
</dependency>
<dependency>
<groupId>javax.jdo</groupId>
<artifactId>jdo2-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>transaction-api</artifactId>
<version>[1.1-rev-1,)</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0b</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.datanucleus</groupId>
<artifactId>maven-datanucleus-plugin</artifactId>
<version>3.1.0-m3</version>
<configuration>
<log4jConfiguration>${basedir}/log4j.properties</log4jConfiguration>
<verbose>true</verbose>
</configuration>
<executions>
<execution>
<phase>process-classes</phase>
<goals>
<goal>enhance</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
此代碼工作正常。
當我嘗試部署使用相同代碼的應用程序時,發生的第一件事是GF無法找到某些類。這些類雖然在.ear文件中。我哈得把幾個班的GF_HOME/GlassFish中/域// lib目錄,使GF能夠找到類,但我終於結束了一個例外
Caused by: javax.persistence.PersistenceException: No Persistence provider for EntityManager named just_test
值得一提的是org.datanucleus .api.jpa.PersistenceProviderImpl類位於datanucleus-api-jpa文件中,我也將其放入域的lib目錄中。
我也試圖與CDI做類似下面
@PersistenceContext(unitName = "just_test")
protected EntityManager entityManager;
@Override
public void persist(TestEntity testEntity) {
entityManager.persist(testEntity);
}
這apprach也未成功。我有一個例外
java.lang.ClassCastException: Cannot cast org.datanucleus.api.jpa.PersistenceProviderImpl to javax.persistence.spi.PersistenceProvider
任何想法或鏈接到aticles和/或文檔將不勝感激。謝謝
下面是我嘗試在Glassfish上部署的應用程序使用的依賴項列表。所有具有'提供'範圍的依賴關係我必須放入Glassfish的lib目錄中
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-core</artifactId>
<version>[2.9,)</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-mongodb</artifactId>
<version>[2.9,)</version>
</dependency>
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-api-jpa</artifactId>
<version>[3.0,)</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jpa_2.0_spec</artifactId>
<version>[1.0,)</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-api-jdo</artifactId>
<version>[3.0,)</version>
</dependency>
<dependency>
<groupId>javax.jdo</groupId>
<artifactId>jdo2-api</artifactId>
<version>2.2</version>
</dependency>
您似乎在JPA2 jar(geronimo-jpa_2.0_spec)的CLASSPATH中有JPA1 jar(javax.persistence)。如果我是你,我會在其他任何事情之前決定我想使用哪個版本的JPA。很明顯,在那裏使用的DN版本完全實現了JPA2 – DataNucleus
@DataNucleus感謝您的評論。這種依賴性在那裏,因爲我首先找到了JPA1的例子,並修改了使用JPA2的代碼。我刪除了不必要的依賴,但它沒有幫助。我有相同的堆棧跟蹤。我也修改了我的帖子,並把我用於GF的整個依賴列表。 – jjd
由於某些原因,當該版本的DN實現JDO 3.0時,您有JDO 2.2。 Glassfish將在某處存在自己的JPA.jar,因此可能它不想要另一個或者感到困惑。事實是,「org.datanucleus.api.jpa.PersistenceProviderImpl」完全實現了javax.persistence.spi.PersistenceProvider,所以它的一個類加載的東西 – DataNucleus