2011-11-01 22 views
2

當我執行斯卡拉REPL下面的代碼:JPA/SCALA否持久性提供者名爲xxx?

javax.persistence.Persistence.createEntityManagerFactory("manager1") 

我得到

javax.persistence.PersistenceException: No Persistence provider for EntityManager named manager1 

運行Java同樣的Maven項目有沒有問題(換句話說,我相信我的依賴條件是設置正確)

使用遠程調試器我發現問題似乎是在PersistenceProviderResolverHolder它執行以下代碼:

Enumeration<URL> resources = cl.getResources("META-INF/services/" + PersistenceProvider.class.getName()) 

返回的枚舉沒有元素。

當我執行相同的REPL會話

val cl = classOf[javax.persistence.spi.PersistenceProviderResolverHolder].getClassLoader() 
cl.getResources("META-INF/services/javax.persistence.spi.PersistenceProvider").hasMoreElements 

我得到 「真」

發生這種情況都使用MVN時:斯卡拉或直接使用Scala的時候:

scala -cp "target/dependency/*":target/classes 

我的依賴是

[INFO] --- maven-dependency-plugin:2.3:tree (default-cli) @ java.jpa.basics --- 
[INFO] com.edc4it:java.jpa.basics:jar:1.0 
[INFO] +- org.slf4j:slf4j-log4j12:jar:1.6.2:compile 
[INFO] | +- org.slf4j:slf4j-api:jar:1.6.2:compile 
[INFO] | \- log4j:log4j:jar:1.2.16:compile 
[INFO] +- mysql:mysql-connector-java:jar:5.1.6:compile 
[INFO] +- javassist:javassist:jar:3.9.0.GA:compile 
[INFO] +- org.scala-lang:scala-library:jar:2.9.1:compile 
[INFO] \- org.hibernate:hibernate-entitymanager:jar:3.6.7.Final:compile 
[INFO] +- org.hibernate:hibernate-core:jar:3.6.7.Final:compile 
[INFO] | +- antlr:antlr:jar:2.7.6:compile 
[INFO] | +- commons-collections:commons-collections:jar:3.1:compile 
[INFO] | +- dom4j:dom4j:jar:1.6.1:compile 
[INFO] | +- org.hibernate:hibernate-commons-annotations:jar:3.2.0.Final:compile 
[INFO] | \- javax.transaction:jta:jar:1.1:compile 
[INFO] +- cglib:cglib:jar:2.2:compile 
[INFO] | \- asm:asm:jar:3.1:compile 
[INFO] \- org.hibernate.javax.persistence:hibernate-jpa-2.0-api:jar:1.0.1.Final:compile 

唯一的JPA相關依賴是「org.hibernate:hibernate-entitymanager:3.6.7.Final」

它看起來像一個類加載問題,但它可能是不同的東西?

+0

嘗試'-Yrepl-sync'。 – soc

回答

1

經過一些更多的挖掘和調試之後,我發現JPA實現使用當前腳本的上下文類加載器(在我的情況下是sun.misc.Launcher $ AppClassLoader)。該類加載器確實不包含JPA和Hibernate JAR。 (見javax.persistence.spi.PersistenceProviderResolverHolder.PersistenceProviderResolverPerClassLoader#getContextualClassLoader) 因此獲得EntityManagerFactory的做的伎倆之前更改上下文類加載器:

Thread.currentThread().setContextClassLoader(JPAUtil.class.getClassLoader()); 
emf = Persistence.createEntityManagerFactory("manager"); 

在REPL設置上下文類加載器不工作,將被重置爲應用程序類加載器設置後。我不知道是否所有的JPA代碼都能正常工作,只是做了一些測試,看起來目前工作得很好。 另外我不明白爲什麼hibernate會使用上下文類加載器,而不僅僅是當前的類加載器。

相關問題