2012-11-21 354 views
3

我在使用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> 
+0

您似乎在JPA2 jar(geronimo-jpa_2.0_spec)的CLASSPATH中有JPA1 jar(javax.persistence)。如果我是你,我會在其他任何事情之前決定我想使用哪個版本的JPA。很明顯,在那裏使用的DN版本完全實現了JPA2 – DataNucleus

+0

@DataNucleus感謝您的評論。這種依賴性在那裏,因爲我首先找到了JPA1的例子,並修改了使用JPA2的代碼。我刪除了不必要的依賴,但它沒有幫助。我有相同的堆棧跟蹤。我也修改了我的帖子,並把我用於GF的整個依賴列表。 – jjd

+0

由於某些原因,當該版本的DN實現JDO 3.0時,您有JDO 2.2。 Glassfish將在某處存在自己的JPA.jar,因此可能它不想要另一個或者感到困惑。事實是,「org.datanucleus.api.jpa.PersistenceProviderImpl」完全實現了javax.persistence.spi.PersistenceProvider,所以它的一個類加載的東西 – DataNucleus

回答

0

我設法解決它。我有如下圖所示

<properties> 
    <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir> 
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
    <datanucleus.version>3.1.3</datanucleus.version> 
</properties> 

<dependencies> 
    <dependency> 
     <groupId>org.datanucleus</groupId> 
     <artifactId>datanucleus-core</artifactId> 
     <version>${datanucleus.version}</version> 
     <scope>provided</scope> 
    </dependency> 
    <dependency> 
     <groupId>org.datanucleus</groupId> 
     <artifactId>datanucleus-mongodb</artifactId> 
     <version>${datanucleus.version}</version> 
     <scope>provided</scope> 
    </dependency> 
    <dependency> 
     <groupId>org.datanucleus</groupId> 
     <artifactId>datanucleus-api-jpa</artifactId> 
     <version>${datanucleus.version}</version> 
     <scope>provided</scope> 
    </dependency> 
    <dependency> 
     <groupId>org.datanucleus</groupId> 
     <artifactId>datanucleus-api-jdo</artifactId> 
     <version>${datanucleus.version}</version> 
     <scope>provided</scope> 
    </dependency> 
    <dependency> 
     <groupId>javax.jdo</groupId> 
     <artifactId>jdo2-api</artifactId> 
     <version>2.2</version> 
     <scope>provided</scope> 
    </dependency> 
</dependencies> 

我也只好把那些「提供」範圍的GF_HOME/GlassFish中/域// lib目錄下的所有jar文件修改的依賴關係。我不知道爲什麼我必須這樣做。這將是一個很好的答案。希望可以節省時間給想要使用Glassfish的Datanucleus的人