带有JPA错误的多个`@ ElementCollection:[PersistenceUnit:JPA]无法构建EntityManagerFactory

时间:2018-03-06 09:07:04

标签: java hibernate jpa enums playframework-2.0

我无法在Play Framework环境中使用JPA实现具有常量类型集合的多个属性的模型。

多次@ElementCollectionCollection次使用Enum注释会导致错误,这样一个带注释的属性不会导致错误和正确行为。

问题通过https://github.com/adpes/jpa-elementcollection-mvce/tree/elementcollection-double进行了演示,并在README.md

中进行了说明
  

这个fork演示了重复注释JPA的问题   Play Framework环境中的@ElementCollection。看文件,   除了states之外,特别是属性languages

           

如果使用注释了多个属性,则构建失败   @ElementCollection

以下模型Person会产生以下堆栈跟踪:

models/Person.java

package models;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.Collection;

@Entity
public class Person {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    public Long id;

    public String name;

    @ElementCollection(targetClass = Languages.class, fetch = FetchType.EAGER)
    public Collection<Languages> languages = new ArrayList<>();

    // TODO Comment me and the build will succeed
    @ElementCollection(targetClass = State.class, fetch = FetchType.EAGER)
    public Collection<State> states = new ArrayList<>();
}

堆栈跟踪

sbt run
[info] Loading settings from idea.sbt ...
[info] Loading global plugins from /home/adpes/.sbt/1.0/plugins
[info] Loading settings from plugins.sbt ...
[info] Loading project definition from /home/adpes/dev/jpa-elementcollection-mvce/project
[info] Loading settings from build.sbt ...
[info] Set current project to play-java-jpa-example (in build file:/home/adpes/dev/jpa-elementcollection-mvce/)

--- (Running the application, auto-reloading is enabled) ---

[info] p.c.s.AkkaHttpServer - Listening for HTTP on /0:0:0:0:0:0:0:0:9000

(Server started, use Enter to stop and go back to the console...)

Warning: node.js detection failed, sbt will use the Rhino based Trireme JavaScript engine instead to run JavaScript assets compilation, which in some cases may be orders of magnitude slower than using node.js.
[info] application - Creating Pool for datasource 'default'
[info] p.a.d.HikariCPConnectionPool - datasource [default] bound to JNDI as DefaultDS
[info] p.a.d.DefaultDBApi - Database [default] connected at jdbc:h2:mem:play
[warn] o.h.v.m.ParameterMessageInterpolator - HV000184: ParameterMessageInterpolator has been chosen, EL interpolation will not be supported
[info] p.a.h.EnabledFilters - Enabled Filters (see <https://www.playframework.com/documentation/latest/Filters>):

    play.filters.csrf.CSRFFilter
    play.filters.headers.SecurityHeadersFilter
    play.filters.hosts.AllowedHostsFilter

[error] application - 

! @777cf90c8 - Internal server error, for (GET) [/] ->

play.api.UnexpectedException: Unexpected exception[ProvisionException: Unable to provision, see the following errors:

1) Error injecting constructor, javax.persistence.PersistenceException: [PersistenceUnit: defaultPersistenceUnit] Unable to build Hibernate SessionFactory
  at play.db.jpa.DefaultJPAApi$JPAApiProvider.<init>(DefaultJPAApi.java:44)
  at play.db.jpa.DefaultJPAApi$JPAApiProvider.class(DefaultJPAApi.java:39)
  while locating play.db.jpa.DefaultJPAApi$JPAApiProvider
  while locating play.db.jpa.JPAApi
    for the 1st parameter of models.JPAPersonRepository.<init>(JPAPersonRepository.java:23)
  while locating models.JPAPersonRepository
  while locating models.PersonRepository
    for the 2nd parameter of controllers.PersonController.<init>(PersonController.java:28)
  while locating controllers.PersonController
    for the 2nd parameter of router.Routes.<init>(Routes.scala:30)
  while locating router.Routes
  while locating play.api.inject.RoutesProvider
  while locating play.api.routing.Router
    for the 1st parameter of play.api.http.JavaCompatibleHttpRequestHandler.<init>(HttpRequestHandler.scala:222)
  while locating play.api.http.JavaCompatibleHttpRequestHandler
  while locating play.api.http.HttpRequestHandler
    for the 6th parameter of play.api.DefaultApplication.<init>(Application.scala:236)
  at play.api.DefaultApplication.class(Application.scala:235)
  while locating play.api.DefaultApplication
  while locating play.api.Application

1 error]
    at play.core.server.DevServerStart$$anon$1.reload(DevServerStart.scala:186)
    at play.core.server.DevServerStart$$anon$1.get(DevServerStart.scala:124)
    at play.core.server.AkkaHttpServer.handleRequest(AkkaHttpServer.scala:189)
    at play.core.server.AkkaHttpServer.$anonfun$createServerBinding$1(AkkaHttpServer.scala:106)
    at akka.stream.impl.fusing.MapAsync$$anon$25.onPush(Ops.scala:1194)
    at akka.stream.impl.fusing.GraphInterpreter.processPush(GraphInterpreter.scala:519)
    at akka.stream.impl.fusing.GraphInterpreter.processEvent(GraphInterpreter.scala:482)
    at akka.stream.impl.fusing.GraphInterpreter.execute(GraphInterpreter.scala:378)
    at akka.stream.impl.fusing.GraphInterpreterShell.runBatch(ActorGraphInterpreter.scala:585)
    at akka.stream.impl.fusing.GraphInterpreterShell$AsyncInput.execute(ActorGraphInterpreter.scala:469)
Caused by: com.google.inject.ProvisionException: Unable to provision, see the following errors:

1) Error injecting constructor, javax.persistence.PersistenceException: [PersistenceUnit: defaultPersistenceUnit] Unable to build Hibernate SessionFactory
  at play.db.jpa.DefaultJPAApi$JPAApiProvider.<init>(DefaultJPAApi.java:44)
  at play.db.jpa.DefaultJPAApi$JPAApiProvider.class(DefaultJPAApi.java:39)
  while locating play.db.jpa.DefaultJPAApi$JPAApiProvider
  while locating play.db.jpa.JPAApi
    for the 1st parameter of models.JPAPersonRepository.<init>(JPAPersonRepository.java:23)
  while locating models.JPAPersonRepository
  while locating models.PersonRepository
    for the 2nd parameter of controllers.PersonController.<init>(PersonController.java:28)
  while locating controllers.PersonController
    for the 2nd parameter of router.Routes.<init>(Routes.scala:30)
  while locating router.Routes
  while locating play.api.inject.RoutesProvider
  while locating play.api.routing.Router
    for the 1st parameter of play.api.http.JavaCompatibleHttpRequestHandler.<init>(HttpRequestHandler.scala:222)
  while locating play.api.http.JavaCompatibleHttpRequestHandler
  while locating play.api.http.HttpRequestHandler
    for the 6th parameter of play.api.DefaultApplication.<init>(Application.scala:236)
  at play.api.DefaultApplication.class(Application.scala:235)
  while locating play.api.DefaultApplication
  while locating play.api.Application

1 error
    at com.google.inject.internal.InjectorImpl$2.get(InjectorImpl.java:1028)
    at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1054)
    at play.api.inject.guice.GuiceInjector.instanceOf(GuiceInjectorBuilder.scala:409)
    at play.api.inject.guice.GuiceInjector.instanceOf(GuiceInjectorBuilder.scala:404)
    at play.api.inject.ContextClassLoaderInjector.$anonfun$instanceOf$2(Injector.scala:117)
    at play.api.inject.ContextClassLoaderInjector.withContext(Injector.scala:126)
    at play.api.inject.ContextClassLoaderInjector.instanceOf(Injector.scala:117)
    at play.api.inject.guice.GuiceApplicationBuilder.build(GuiceApplicationBuilder.scala:137)
    at play.api.inject.guice.GuiceApplicationLoader.load(GuiceApplicationLoader.scala:21)
    at play.core.server.DevServerStart$$anon$1.$anonfun$reload$3(DevServerStart.scala:174)
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: defaultPersistenceUnit] Unable to build Hibernate SessionFactory
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:967)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:892)
    at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:58)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:39)
    at play.db.jpa.DefaultJPAApi.lambda$start$1(DefaultJPAApi.java:65)
    at java.lang.Iterable.forEach(Iterable.java:75)
    at play.db.jpa.DefaultJPAApi.start(DefaultJPAApi.java:64)
    at play.db.jpa.DefaultJPAApi$JPAApiProvider.<init>(DefaultJPAApi.java:51)
    at play.db.jpa.DefaultJPAApi$JPAApiProvider$$FastClassByGuice$$dcd4cdbd.newInstance(<generated>)
Caused by: org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags: [models.Person.languages, models.Person.states]
    at org.hibernate.loader.plan.exec.internal.AbstractLoadQueryDetails.generate(AbstractLoadQueryDetails.java:178)
    at org.hibernate.loader.plan.exec.internal.EntityLoadQueryDetails.<init>(EntityLoadQueryDetails.java:90)
    at org.hibernate.loader.plan.exec.internal.BatchingLoadQueryDetailsFactory.makeEntityLoadQueryDetails(BatchingLoadQueryDetailsFactory.java:61)
    at org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader.<init>(AbstractLoadPlanBasedEntityLoader.java:82)
    at org.hibernate.loader.entity.plan.EntityLoader.<init>(EntityLoader.java:103)
    at org.hibernate.loader.entity.plan.EntityLoader.<init>(EntityLoader.java:38)
    at org.hibernate.loader.entity.plan.EntityLoader$Builder.byUniqueKey(EntityLoader.java:83)
    at org.hibernate.loader.entity.plan.EntityLoader$Builder.byPrimaryKey(EntityLoader.java:77)
    at org.hibernate.loader.entity.plan.AbstractBatchingEntityLoaderBuilder.buildNonBatchingLoader(AbstractBatchingEntityLoaderBuilder.java:30)
    at org.hibernate.loader.entity.BatchingEntityLoaderBuilder.buildLoader(BatchingEntityLoaderBuilder.java:59)
[error] application - 

! @777cf90c8 - Internal server error, for (GET) [/favicon.ico] ->

play.api.UnexpectedException: Unexpected exception[ProvisionException: Unable to provision, see the following errors:

1) Error injecting constructor, javax.persistence.PersistenceException: [PersistenceUnit: defaultPersistenceUnit] Unable to build Hibernate SessionFactory
  at play.db.jpa.DefaultJPAApi$JPAApiProvider.<init>(DefaultJPAApi.java:44)
  at play.db.jpa.DefaultJPAApi$JPAApiProvider.class(DefaultJPAApi.java:39)
  while locating play.db.jpa.DefaultJPAApi$JPAApiProvider
  while locating play.db.jpa.JPAApi
    for the 1st parameter of models.JPAPersonRepository.<init>(JPAPersonRepository.java:23)
  while locating models.JPAPersonRepository
  while locating models.PersonRepository
    for the 2nd parameter of controllers.PersonController.<init>(PersonController.java:28)
  while locating controllers.PersonController
    for the 2nd parameter of router.Routes.<init>(Routes.scala:30)
  while locating router.Routes
  while locating play.api.inject.RoutesProvider
  while locating play.api.routing.Router
    for the 1st parameter of play.api.http.JavaCompatibleHttpRequestHandler.<init>(HttpRequestHandler.scala:222)
  while locating play.api.http.JavaCompatibleHttpRequestHandler
  while locating play.api.http.HttpRequestHandler
    for the 6th parameter of play.api.DefaultApplication.<init>(Application.scala:236)
  at play.api.DefaultApplication.class(Application.scala:235)
  while locating play.api.DefaultApplication
  while locating play.api.Application

1 error]
    at play.core.server.DevServerStart$$anon$1.reload(DevServerStart.scala:186)
    at play.core.server.DevServerStart$$anon$1.get(DevServerStart.scala:124)
    at play.core.server.AkkaHttpServer.handleRequest(AkkaHttpServer.scala:189)
    at play.core.server.AkkaHttpServer.$anonfun$createServerBinding$1(AkkaHttpServer.scala:106)
    at akka.stream.impl.fusing.MapAsync$$anon$25.onPush(Ops.scala:1194)
    at akka.stream.impl.fusing.GraphInterpreter.processPush(GraphInterpreter.scala:519)
    at akka.stream.impl.fusing.GraphInterpreter.processEvent(GraphInterpreter.scala:482)
    at akka.stream.impl.fusing.GraphInterpreter.execute(GraphInterpreter.scala:378)
    at akka.stream.impl.fusing.GraphInterpreterShell.runBatch(ActorGraphInterpreter.scala:585)
    at akka.stream.impl.fusing.GraphInterpreterShell$AsyncInput.execute(ActorGraphInterpreter.scala:469)
Caused by: com.google.inject.ProvisionException: Unable to provision, see the following errors:

1) Error injecting constructor, javax.persistence.PersistenceException: [PersistenceUnit: defaultPersistenceUnit] Unable to build Hibernate SessionFactory
  at play.db.jpa.DefaultJPAApi$JPAApiProvider.<init>(DefaultJPAApi.java:44)
  at play.db.jpa.DefaultJPAApi$JPAApiProvider.class(DefaultJPAApi.java:39)
  while locating play.db.jpa.DefaultJPAApi$JPAApiProvider
  while locating play.db.jpa.JPAApi
    for the 1st parameter of models.JPAPersonRepository.<init>(JPAPersonRepository.java:23)
  while locating models.JPAPersonRepository
  while locating models.PersonRepository
    for the 2nd parameter of controllers.PersonController.<init>(PersonController.java:28)
  while locating controllers.PersonController
    for the 2nd parameter of router.Routes.<init>(Routes.scala:30)
  while locating router.Routes
  while locating play.api.inject.RoutesProvider
  while locating play.api.routing.Router
    for the 1st parameter of play.api.http.JavaCompatibleHttpRequestHandler.<init>(HttpRequestHandler.scala:222)
  while locating play.api.http.JavaCompatibleHttpRequestHandler
  while locating play.api.http.HttpRequestHandler
    for the 6th parameter of play.api.DefaultApplication.<init>(Application.scala:236)
  at play.api.DefaultApplication.class(Application.scala:235)
  while locating play.api.DefaultApplication
  while locating play.api.Application

1 error
    at com.google.inject.internal.InjectorImpl$2.get(InjectorImpl.java:1028)
    at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1054)
    at play.api.inject.guice.GuiceInjector.instanceOf(GuiceInjectorBuilder.scala:409)
    at play.api.inject.guice.GuiceInjector.instanceOf(GuiceInjectorBuilder.scala:404)
    at play.api.inject.ContextClassLoaderInjector.$anonfun$instanceOf$2(Injector.scala:117)
    at play.api.inject.ContextClassLoaderInjector.withContext(Injector.scala:126)
    at play.api.inject.ContextClassLoaderInjector.instanceOf(Injector.scala:117)
    at play.api.inject.guice.GuiceApplicationBuilder.build(GuiceApplicationBuilder.scala:137)
    at play.api.inject.guice.GuiceApplicationLoader.load(GuiceApplicationLoader.scala:21)
    at play.core.server.DevServerStart$$anon$1.$anonfun$reload$3(DevServerStart.scala:174)
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: defaultPersistenceUnit] Unable to build Hibernate SessionFactory
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:967)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:892)
    at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:58)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:39)
    at play.db.jpa.DefaultJPAApi.lambda$start$1(DefaultJPAApi.java:65)
    at java.lang.Iterable.forEach(Iterable.java:75)
    at play.db.jpa.DefaultJPAApi.start(DefaultJPAApi.java:64)
    at play.db.jpa.DefaultJPAApi$JPAApiProvider.<init>(DefaultJPAApi.java:51)
    at play.db.jpa.DefaultJPAApi$JPAApiProvider$$FastClassByGuice$$dcd4cdbd.newInstance(<generated>)
Caused by: org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags: [models.Person.languages, models.Person.states]
    at org.hibernate.loader.plan.exec.internal.AbstractLoadQueryDetails.generate(AbstractLoadQueryDetails.java:178)
    at org.hibernate.loader.plan.exec.internal.EntityLoadQueryDetails.<init>(EntityLoadQueryDetails.java:90)
    at org.hibernate.loader.plan.exec.internal.BatchingLoadQueryDetailsFactory.makeEntityLoadQueryDetails(BatchingLoadQueryDetailsFactory.java:61)
    at org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader.<init>(AbstractLoadPlanBasedEntityLoader.java:82)
    at org.hibernate.loader.entity.plan.EntityLoader.<init>(EntityLoader.java:103)
    at org.hibernate.loader.entity.plan.EntityLoader.<init>(EntityLoader.java:38)
    at org.hibernate.loader.entity.plan.EntityLoader$Builder.byUniqueKey(EntityLoader.java:83)
    at org.hibernate.loader.entity.plan.EntityLoader$Builder.byPrimaryKey(EntityLoader.java:77)
    at org.hibernate.loader.entity.plan.AbstractBatchingEntityLoaderBuilder.buildNonBatchingLoader(AbstractBatchingEntityLoaderBuilder.java:30)
    at org.hibernate.loader.entity.BatchingEntityLoaderBuilder.buildLoader(BatchingEntityLoaderBuilder.java:59)
[info] p.c.s.AkkaHttpServer - Stopping server...

[success] Total time: 21 s, completed Mar 6, 2018 9:15:27 AM
[INFO] [03/06/2018 09:15:28.031] [Thread-2] [CoordinatedShutdown(akka://sbt-web)] Starting coordinated shutdown from JVM shutdown hook

1 个答案:

答案 0 :(得分:0)

我知道我参加晚会很晚,但是请参阅下文,我对您的代码进行了更改。更改仍然使您急切地寻找所需的内容。

package models;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.Collection;

@Entity
public class Person {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    public Long id;

    public String name;

    @ElementCollection(targetClass = Languages.class) // remove fetch type
    @LazyCollection(LazyCollectionOption.FALSE)// This I have found to be my saving grace
    public Collection<Languages> languages = new ArrayList<>();

    // TODO Comment me and the build will succeed
    @ElementCollection(targetClass = State.class) // remove fetch type
    @LazyCollection(LazyCollectionOption.FALSE) // This I have found to be my saving grace
    public Collection<State> states = new ArrayList<>();
}