2016-01-13 69 views
0

我已經寫了(使用Eclipse)一個使用JPA的小程序。現在我想手動編譯並使用命令行運行此程序。我還將所有源文件放在一個單獨的目錄中(不在Eclipse的工作空間內)。該目錄是這樣的:PersistenceException:否EntityManager的持久性提供者名爲

directory 
    |- src 
    | |- javax 
    | | |- persistence 
    | |  |- <...> 
    | |- main 
    | |- META-INF 
    | | |- javax 
    | | | |- persistence 
    | | |- persistence.xml 
    | | 
    | |- <..> 
    |- run.bat 

注:我故意有2個在他們的所有類文件的javax目錄。

run.bat中所包含的行:

javac -cp ./src ./src/main/Main.java 
java -cp ./src main.Main 

據我瞭解,我越來越不符合META-INF/persistence.xml文件的問題,因爲錯誤的(不象其他許多人對計算器) 。我這樣說,因爲我已經writen按照我的主線:

<...> 
Thread.currentThread().setContextClassLoader(new ClassLoader() { 
      @Override 
      public Enumeration<URL> getResources(String name) throws IOException { 
       System.out.println("resource requested=" + name); 
       if (name.equals("META-INF/services/javax.persistence.spi.PersistenceProvider")) { 
     <--- MARK --->  return Collections.enumeration(Arrays.asList(new File("src/javax/persistence/spi/PersistenceProvider.class") 
          .toURI().toURL())); 
       } else if (name.equals("META-INF/persistence.xml")) { 
        return Collections.enumeration(Arrays.asList(new File("src/META-INF/persistence.xml") 
          .toURI().toURL())); 
       } 
       return super.getResources(name); 
      } 
     }); 
emFactory = Persistence.createEntityManagerFactory("uzduotis"); 
<...> 

所以,當我啓動的run.bat程序打印:

resource name=name=META-INF/services/javax.persistence.spi.PersistenceProvider

(它從來沒有獲取到部分地方計劃詢問 「META-INF/persistence.xml中」 資源)

那麼它打破了,給我一個錯誤:

enter image description here

如果我改變註明聲明

return super.getResources("src/" + name); 

,則錯誤只是說:

enter image description here

我缺少什麼?

Peristence.xml:

enter image description here

編輯: 計劃prety簡單:沒有休眠,只是它檢索REST服務的一些信息,並與它的工作,主要是使用的javax幾類和w3c外部庫。項目瀏覽器的照片來描繪其簡單性。

enter image description here

編輯2.解決方案

我找到了一種方法,使其工作雖然我不能完全肯定的原因。所以如果有人能回答爲什麼以下更改解決了問題,我會很樂意將其標記爲一個答案

我加和的EclipseLink使用mysql-connector-java的罐子到SRC目錄。 eclipselink.jar修復了這個問題,並且需要mysql-connector-java.jar,因爲我得到了其他錯誤(我正在使用數據庫)。最後我在運行中改變了路線。從

java -cp ./src main.Main 

bat文件到

java -cp ./src;./src/eclipselink.jar;./src/mysql-connector-java.jar; main.Main 
+0

也許這個答案可以幫助:http://stackoverflow.com/a/1285436/1506009 – Rozart

+0

該帖子的哪個部分認爲可以解決我的問題? – sdafsDGZvb

+0

好像你沒有在你的persistence.xml文件中指定持久性提供者。所以我會嘗試在鏈接的答案中指定它。 只需在'persistence unit name =「uzduotis」>元素內添加' org.hibernate.ejb.HibernatePersistence'。請記住,您需要爲HibernatePersistence解決依賴關係。 – Rozart

回答

0

看來,你的應用程序是一個標準的Java SE應用程序。 JPA不會自動工作,因爲標準Java SE環境不包含任何JPA接口的實現。看來Eclipse將eclipselink添加到封面下的類路徑中,因此當您在Eclipse中運行它時,您的程序將工作。但是,當從命令行運行程序時,需要添加eclipselink,它是一個包含JPA接口功能的庫。

您可以嘗試從eclipse項目生成Ant構建文件,並且您會看到它是否將eclipselink添加到build.xml文件中的類路徑中。或者更好,我建議使用Maven構建項目來將項目變成項目 - 您將能夠使用Maven命令構建和運行項目,就像Eclipse執行項目一樣(因爲Eclipse使用Maven編寫的基於Maven的封面項目)。

編輯 - 的EclipseLink的JPA中

開始javax.persistence多接口,標註包裝作用的解釋,他們其實很少類​​。它們僅以標準方式定義應用程序如何與基礎持久性機制進行通信。另一方面,您還需要包含具有標準JPA接口的實現(類)的庫。 javax.persistence.Persistence只是一個外觀,它將所有的辛苦工作委託給一個實現,可能是Eclipselink,Hibernate或其他。

javax.persistence和EclipseLink之間的關係類似於接口和類之間的關係。你可以在你的代碼中使用接口,但是你的應用程序只有在某些時候提供真實類的接口時才能工作。

也可以直接使用Eclipselink並跳過整個javax.persistence圖層,類似於可以直接使用真實類而不通過接口。但是,那麼你需要學習Eclipselink的內部API,並且不可能爲Eclipselink庫更改Hibernate等替代方法。您也不能將Eclipselink特定API的知識用於使用Hibernate的項目。標準API的可重用性是標準化接口的最重要的情況。

也許你想知道,持久性API如何知道應該在哪裏委託所需的功能。有多個鉤子,它是如何發現的。可以使用provider元素在persistence.xml中包含主實現類的路徑。或者,如果您將Eclipselink包含到類路徑中,它就會起作用,因爲Eclipselink庫在包含所需信息的標準化路徑中包含特殊文本文件。這個特殊的文件在Eclipselink JAR中,路徑爲META-INF/services/javax.persistence.spi.PersistenceProvider - 它響鈴嗎?

+0

您能否詳細介紹eclipselink在這種情況下的確切做法以及爲什麼javax沒有如此需要的implmenetations? – sdafsDGZvb

+0

我在答案中增加了更多解釋。 – OndrejM

+0

看看這個問題http://stackoverflow.com/questions/19322827/no-persistence-provider-for-entitymanager-named-x/22224589#22224589。它包含其他技術細節。 – OndrejM

相關問題