【问题标题】:PlayFramework. Use transaction in entity constructor播放框架。在实体构造函数中使用事务
【发布时间】:2015-11-10 01:03:13
【问题描述】:

我正在尝试在其他实体构造函数中获取实体列表。

不幸的是,它在运行时失败。

这里是构造函数:

public Contract_Answer() {
    this.commonEntities = CommonEntityDao.getList();
}

这是我的整个堆栈跟踪:

play.api.UnexpectedException: Unexpected exception[PersistenceException: [PersistenceUnit: defaultPersistenceUnit] Unable to build EntityManagerFactory]
        at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:148) ~[play_2.10.jar:2.2.6]
        at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:112) ~[play_2.10.jar:2.2.6]
        at scala.Option.map(Option.scala:145) ~[scala-library.jar:na]
        at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1.apply(ApplicationProvider.scala:112) ~[play_2.10.jar:2.2.6]
        at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1.apply(ApplicationProvider.scala:110) ~[play_2.10.jar:2.2.6]
        at scala.util.Success.flatMap(Try.scala:200) ~[scala-library.jar:na]
        at play.core.ReloadableApplication$$anonfun$get$1.apply(ApplicationProvider.scala:110) ~[play_2.10.jar:2.2.6]
        at play.core.ReloadableApplication$$anonfun$get$1.apply(ApplicationProvider.scala:102) ~[play_2.10.jar:2.2.6]
        at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24) ~[scala-library.jar:na]
        at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24) ~[scala-library.jar:na]
        at scala.concurrent.forkjoin.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1361) ~[scala-library.jar:na]
        at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) ~[scala-library.jar:na]
        at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339) ~[scala-library.jar:na]
        at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) ~[scala-library.jar:na]
        at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107) ~[scala-library.jar:na]
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: defaultPersistenceUnit] Unable to build EntityManagerFactory
        at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:915) ~[hibernate-entitymanager-4.2.0.CR1.jar:4.2.0.CR1]
        at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:890) ~[hibernate-entitymanager-4.2.0.CR1.jar:4.2.0.CR1]
        at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:57) ~[hibernate-entitymanager-4.2.0.CR1.jar:4.2.0.CR1]
        at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:63) ~[hibernate-jpa-2.0-api.jar:1.0.1.Final]
        at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:47) ~[hibernate-jpa-2.0-api.jar:1.0.1.Final]
        at play.db.jpa.JPAPlugin.onStart(JPAPlugin.java:35) ~[play-java-jpa_2.10.jar:2.2.6]
        at play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:88) ~[play_2.10.jar:2.2.6]
        at play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:88) ~[play_2.10.jar:2.2.6]
        at scala.collection.immutable.List.foreach(List.scala:318) ~[scala-library.jar:na]
        at play.api.Play$$anonfun$start$1.apply$mcV$sp(Play.scala:88) ~[play_2.10.jar:2.2.6]
        at play.api.Play$$anonfun$start$1.apply(Play.scala:88) ~[play_2.10.jar:2.2.6]
        at play.api.Play$$anonfun$start$1.apply(Play.scala:88) ~[play_2.10.jar:2.2.6]
        at play.utils.Threads$.withContextClassLoader(Threads.scala:18) ~[play_2.10.jar:2.2.6]
        at play.api.Play$.start(Play.scala:87) ~[play_2.10.jar:2.2.6]
        at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:139) ~[play_2.10.jar:2.2.6]
        ... 14 common frames omitted
Caused by: org.hibernate.MappingException: Could not get constructor for org.hibernate.persister.entity.SingleTableEntityPersister
        at org.hibernate.persister.internal.PersisterFactoryImpl.create(PersisterFactoryImpl.java:185) ~[hibernate-core-4.2.0.CR1.jar:4.2.0.CR1]
        at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister(PersisterFactoryImpl.java:135) ~[hibernate-core-4.2.0.CR1.jar:4.2.0.CR1]
        at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:385) ~[hibernate-core-4.2.0.CR1.jar:4.2.0.CR1]
        at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1742) ~[hibernate-core-4.2.0.CR1.jar:4.2.0.CR1]
        at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:94) ~[hibernate-entitymanager-4.2.0.CR1.jar:4.2.0.CR1]
        at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:905) ~[hibernate-entitymanager-4.2.0.CR1.jar:4.2.0.CR1]
        ... 28 common frames omitted
Caused by: org.hibernate.InstantiationException: could not instantiate test objectmyInsurance.models.part.Contract_Answer
        at org.hibernate.engine.internal.UnsavedValueFactory.instantiate(UnsavedValueFactory.java:49) ~[hibernate-core-4.2.0.CR1.jar:4.2.0.CR1]
        at org.hibernate.engine.internal.UnsavedValueFactory.getUnsavedIdentifierValue(UnsavedValueFactory.java:68) ~[hibernate-core-4.2.0.CR1.jar:4.2.0.CR1]
        at org.hibernate.tuple.PropertyFactory.buildIdentifierProperty(PropertyFactory.java:75) ~[hibernate-core-4.2.0.CR1.jar:4.2.0.CR1]
        at org.hibernate.tuple.entity.EntityMetamodel.<init>(EntityMetamodel.java:145) ~[hibernate-core-4.2.0.CR1.jar:4.2.0.CR1]
        at org.hibernate.persister.entity.AbstractEntityPersister.<init>(AbstractEntityPersister.java:507) ~[hibernate-core-4.2.0.CR1.jar:4.2.0.CR1]
        at org.hibernate.persister.entity.SingleTableEntityPersister.<init>(SingleTableEntityPersister.java:146) ~[hibernate-core-4.2.0.CR1.jar:4.2.0.CR1]
        at sun.reflect.GeneratedConstructorAccessor317.newInstance(Unknown Source) ~[na:na]
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.7.0_80]
        at java.lang.reflect.Constructor.newInstance(Constructor.java:526) ~[na:1.7.0_80]
        at org.hibernate.persister.internal.PersisterFactoryImpl.create(PersisterFactoryImpl.java:163) ~[hibernate-core-4.2.0.CR1.jar:4.2.0.CR1]
        ... 33 common frames omitted
Caused by: java.lang.reflect.InvocationTargetException: null
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.7.0_80]
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) ~[na:1.7.0_80]
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.7.0_80]
        at java.lang.reflect.Constructor.newInstance(Constructor.java:526) ~[na:1.7.0_80]
        at org.hibernate.engine.internal.UnsavedValueFactory.instantiate(UnsavedValueFactory.java:46) ~[hibernate-core-4.2.0.CR1.jar:4.2.0.CR1]
        ... 42 common frames omitted
Caused by: java.lang.RuntimeException: No EntityManager bound to this thread. Try wrapping this call in JPA.withTransaction, or ensure that the HTTP context is setup on this thread.
        at play.db.jpa.JPA.em(JPA.java:55) ~[play-java-jpa_2.10.jar:2.2.6]
        at generic.models.GenericDictionary.getList(GenericDictionary.java:38) ~[na:na]
        at myInsurance.models.part.Contract_Answer.<init>(Contract_Answer.java:49) ~[na:na]
        ... 47 common frames omitted

请给我你的帮助。我做错了什么?


编辑


感谢@Mon Calamari 的指导,我重写了我的构造函数。不幸的是,这种代码结构对我来说是新的,我无法管理它。

这是新的构造函数:

public Contract_Answer() {
    List<CommonEntity> list = JPA.withTransaction(
            new F.Function0<List<CommonEntity>>() { 
                return CommonEntityDao.getList();
            }
    );
    // doing something with list variable
}

无法编译:

Contract_Answer.java:60: error: illegal start of type
[error]                 return CommonEntityDao.getList();
Contract_Answer.java:60: error: ';' expected
[error]                 return CommonEntityDao.getList();
Contract_Answer.java:60: error: illegal start of type
[error]                 return CommonEntityDao.getList();

EDIT2


最后我编译如下:

public Contract_Answer() {


    List<Contract_PolicyHolderHealthFormQuestion> list = new LinkedList<Contract_PolicyHolderHealthFormQuestion>();
    try {
        list = JPA.withTransaction(
            new play.libs.F.Function0<List<Contract_PolicyHolderHealthFormQuestion>>() {
                @Override
                public List<Contract_PolicyHolderHealthFormQuestion> apply() throws Throwable {
                    return new Contract_PolicyHolderHealthFormQuestion().getList();
                }
            }
        );
    } catch (Throwable e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    for(Contract_PolicyHolderHealthFormQuestion e: list) {
        Contract_PolicyHolderHealthFormAnswer ca = new Contract_PolicyHolderHealthFormAnswer();
        ca.question = e;
        this.answers.add(ca);
    }

}

【问题讨论】:

  • 是的,@Transactional 仅适用于操作方法 - 不适用于构造函数。请改用JPA.withTransaction

标签: database jpa constructor playframework dao


【解决方案1】:

withTransaction包装它

public Contract_Answer() {
    this.commonEntities = JPA.withTransaction(new F.Function0<List<CommonEntity>> () { 
        return CommonEntityDao.getList();
    });
}

【讨论】:

  • 不确定这是否编译,在没有 IDE 支持的情况下发布。
  • 我听从了你的指示。不幸的是它没有编译。查看我更新的帖子以获取更多详细信息。谢谢
【解决方案2】:

答案很简单。您没有任何实体管理器附加到此线程。 有很多解决办法:

  • 最简单的方法是添加到执行此代码注释@Transactional 的方法中
  • 手动开始您的交易:

    EntityManager em = JPA.em(); JPA.bindForCurrentThread(em);

    但如果您决定手动执行此操作,则必须小心并自行提交此事务。决定权在你:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多