使用Ebean在Play Framework 2.3.3中映射@ManyToOne关系的异常

时间:2014-08-19 15:31:58

标签: java jpa orm playframework-2.0 ebean

由于Play Framework 2.3.3中的模型,我无法映射关系。

我有两个模型 GaDataModel BusinessAccounts ,关系 ManyToOne ,模型 GaDataModel 我' m声明类 GaDataModelPK 内的关系,它基本上是@Embedabble PK。

以下课程是我目前的实施。

GaDataModelPK

@Embeddable
public class GaDataModelPK implements Serializable {

    @ManyToOne
    @JoinColumn(nullable = false)
    public BusinessAccount businessAccount;

    @Column(nullable = false)
    public String date;

    @Override
    public boolean equals(Object o) {
        ...
    }

    @Override
    public int hashCode() {
        ...
    }
}

GaDataModel

@Entity
@Table(name = "ga_data_model")
public class GaDataModel extends Model {

    @EmbeddedId
    public GaDataModelPK gaDataModelPK;
        ...
    }
}

BusinessAccounts

@Entity
@Table(name = "business_account")
public class BusinessAccount extends Model {

    @EmbeddedId
    public BusinessAccountPK businessAccountPK;

    public String portal;

    public String region;
    public String category;

    public String hqCountry;
    public String portalCountry;

    @OneToMany(mappedBy = "business_account", cascade = {CascadeType.REMOVE})
    public List<GaDataModel> gaDataModels;

    ...
}

但是当我尝试运行应用程序时,我有以下异常

PLAY WEBBROWSER中的堆栈跟踪

java.lang.RuntimeException: Error reading annotations for repository.models.GaDataModelPK
     com.avaje.ebeaninternal.server.deploy.parse.ReadAnnotations.readAssociations(ReadAnnotations.java:54)
     com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager.readDeployAssociations(BeanDescriptorManager.java:1028)
     com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager.createEmbedded(BeanDescriptorManager.java:455)
     com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager.readEmbeddedDeployment(BeanDescriptorManager.java:478)
     com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager.deploy(BeanDescriptorManager.java:232)
     com.avaje.ebeaninternal.server.core.InternalConfiguration.<init>(InternalConfiguration.java:114)
     com.avaje.ebeaninternal.server.core.DefaultServerFactory.createServer(DefaultServerFactory.java:204)
     com.avaje.ebeaninternal.server.core.DefaultServerFactory.createServer(DefaultServerFactory.java:65)
     com.avaje.ebean.EbeanServerFactory.create(EbeanServerFactory.java:58)
     play.db.ebean.EbeanPlugin.onStart(EbeanPlugin.java:89)
     play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:91)
     play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:91)
     scala.collection.immutable.List.foreach(List.scala:318)
     play.api.Play$$anonfun$start$1.apply$mcV$sp(Play.scala:91)
     play.api.Play$$anonfun$start$1.apply(Play.scala:91)
     play.api.Play$$anonfun$start$1.apply(Play.scala:91)
     play.utils.Threads$.withContextClassLoader(Threads.scala:21)
     play.api.Play$.start(Play.scala:90)
     play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:142)
     play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:115)
     scala.Option.map(Option.scala:145)
     play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1.apply(ApplicationProvider.scala:115)
     play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1.apply(ApplicationProvider.scala:113)
     scala.util.Success.flatMap(Try.scala:200)
     play.core.ReloadableApplication$$anonfun$get$1.apply(ApplicationProvider.scala:113)
     play.core.ReloadableApplication$$anonfun$get$1.apply(ApplicationProvider.scala:105)
     scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
     scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
     scala.concurrent.forkjoin.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1361)
     scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
     scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
     scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)

PLAY CONSOLE中的堆栈跟踪:

    java.lang.NullPointerException: null
    at play.libs.ws.ning.NingWSPlugin.onStop(NingWSPlugin.java:31) ~[play-java-ws_2.10-2.3.1.jar:2.3.1]
    at play.api.Play$$anonfun$stop$1$$anonfun$apply$1$$anonfun$apply$mcV$sp$2.apply(Play.scala:108) [play_2.10-2.3.1.jar:2.3.1]
    at play.api.Play$$anonfun$stop$1$$anonfun$apply$1$$anonfun$apply$mcV$sp$2.apply(Play.scala:107) [play_2.10-2.3.1.jar:2.3.1]
    at scala.collection.immutable.List.foreach(List.scala:318) [scala-library.jar:na]
    at play.api.Play$$anonfun$stop$1$$anonfun$apply$1.apply$mcV$sp(Play.scala:107) [play_2.10-2.3.1.jar:2.3.1]
[info] play - database [default] connected at jdbc:mysql://localhost/analytics
[error] c.a.e.s.d.BeanDescriptorManager - Error in deployment
java.lang.RuntimeException: Error reading annotations for repository.models.GaDataModelPK
    at com.avaje.ebeaninternal.server.deploy.parse.ReadAnnotations.readAssociations(ReadAnnotations.java:54) ~[avaje-ebeanorm-3.3.4.jar:na]
    at com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager.readDeployAssociations(BeanDescriptorManager.java:1028) ~[avaje-ebeanorm-3.3.4.jar:na]
    at com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager.createEmbedded(BeanDescriptorManager.java:455) ~[avaje-ebeanorm-3.3.4.jar:na]
    at com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager.readEmbeddedDeployment(BeanDescriptorManager.java:478) ~[avaje-ebeanorm-3.3.4.jar:na]
    at com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager.deploy(BeanDescriptorManager.java:232) ~[avaje-ebeanorm-3.3.4.jar:na]
Caused by: java.lang.RuntimeException: Error with association to [class repository.models.BusinessAccount] from [repository.models.GaDataModelPK.businessAccount]. Is class repository.models.BusinessAccount registered?
    at com.avaje.ebeaninternal.server.deploy.parse.AnnotationAssocOnes.readManyToOne(AnnotationAssocOnes.java:165) ~[avaje-ebeanorm-3.3.4.jar:na]
    at com.avaje.ebeaninternal.server.deploy.parse.AnnotationAssocOnes.readAssocOne(AnnotationAssocOnes.java:63) ~[avaje-ebeanorm-3.3.4.jar:na]
    at com.avaje.ebeaninternal.server.deploy.parse.AnnotationAssocOnes.parse(AnnotationAssocOnes.java:54) ~[avaje-ebeanorm-3.3.4.jar:na]
    at com.avaje.ebeaninternal.server.deploy.parse.ReadAnnotations.readAssociations(ReadAnnotations.java:45) ~[avaje-ebeanorm-3.3.4.jar:na]
    at com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager.readDeployAssociations(BeanDescriptorManager.java:1028) ~[avaje-ebeanorm-3.3.4.jar:na]
[error] application - 

! @6j99d9gfb - Internal server error, for (GET) [/] ->

play.api.UnexpectedException: Unexpected exception[RuntimeException: Error reading annotations for repository.models.GaDataModelPK]
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:151) ~[play_2.10-2.3.1.jar:2.3.1]
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:115) ~[play_2.10-2.3.1.jar:2.3.1]
    at scala.Option.map(Option.scala:145) ~[scala-library.jar:na]
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1.apply(ApplicationProvider.scala:115) ~[play_2.10-2.3.1.jar:2.3.1]
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1.apply(ApplicationProvider.scala:113) ~[play_2.10-2.3.1.jar:2.3.1]
Caused by: java.lang.RuntimeException: Error reading annotations for repository.models.GaDataModelPK
    at com.avaje.ebeaninternal.server.deploy.parse.ReadAnnotations.readAssociations(ReadAnnotations.java:54) ~[avaje-ebeanorm-3.3.4.jar:na]
    at com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager.readDeployAssociations(BeanDescriptorManager.java:1028) ~[avaje-ebeanorm-3.3.4.jar:na]
    at com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager.createEmbedded(BeanDescriptorManager.java:455) ~[avaje-ebeanorm-3.3.4.jar:na]
    at com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager.readEmbeddedDeployment(BeanDescriptorManager.java:478) ~[avaje-ebeanorm-3.3.4.jar:na]
    at com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager.deploy(BeanDescriptorManager.java:232) ~[avaje-ebeanorm-3.3.4.jar:na]
Caused by: java.lang.RuntimeException: Error with association to [class repository.models.BusinessAccount] from [repository.models.GaDataModelPK.businessAccount]. Is class repository.models.BusinessAccount registered?
    at com.avaje.ebeaninternal.server.deploy.parse.AnnotationAssocOnes.readManyToOne(AnnotationAssocOnes.java:165) ~[avaje-ebeanorm-3.3.4.jar:na]
    at com.avaje.ebeaninternal.server.deploy.parse.AnnotationAssocOnes.readAssocOne(AnnotationAssocOnes.java:63) ~[avaje-ebeanorm-3.3.4.jar:na]
    at com.avaje.ebeaninternal.server.deploy.parse.AnnotationAssocOnes.parse(AnnotationAssocOnes.java:54) ~[avaje-ebeanorm-3.3.4.jar:na]
    at com.avaje.ebeaninternal.server.deploy.parse.ReadAnnotations.readAssociations(ReadAnnotations.java:45) ~[avaje-ebeanorm-3.3.4.jar:na]
    at com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager.readDeployAssociations(BeanDescriptorManager.java:1028) ~[avaje-ebeanorm-3.3.4.jar:na]

2 个答案:

答案 0 :(得分:0)

我有这样的事情:

@OneToMany(mappedBy="contact", targetEntity= gaDataModels.class)

@ManyToOne
@JoinColumn(name="business_account", nullable=false)

那是Play 2.1.1,但我认为没有任何理由说它不起作用。

答案 1 :(得分:0)

要解决此问题,您必须:

  1. 将@ManyToOne关系从GaDataModelPK移动到GaDataModel,然后将属性'insertable'= false和'updateable'= false添加到@JoinColumn注释。
  2. 在GaDataModelPK类中,请保留businessAccountId。
  3. 在GaDataModel中覆盖businessAccount的setter。在这个setter中,我们应该将businessAccount.id写成复合键。
  4. 以下是代码:

    GaDataModel类:

    @Entity
    @Table(name = "ga_data_model")
    public class GaDataModel extends Model {
    
        public GaDataModel(String aDate) {
            gaDataModelPK = new GaDataModelPK();
            gaDataModelPK.date = aDate;
        }
    
        @EmbeddedId
        public GaDataModelPK gaDataModelPK;
    
        @ManyToOne
        @JoinColumn(name = "business_account_id", insertable = false, updatable = false)
        private BusinessAccount businessAccount;
    
        public void setBusinessAccount(BusinessAccount aBusinessAccount) {
            businessAccount = aBusinessAccount;
            gaDataModelPK.businessAccountId = aBusinessAccount.id;
        }
    } 
    

    GaDataModelPK类:

    @Embeddable
    public class GaDataModelPK implements Serializable {
    
        public Long businessAccountId;
    
        @Column(nullable = false)
        public String date;
    
        @Override
        public boolean equals(Object o) {
            return businessAccountId;
        }
    
        @Override
        public int hashCode() {
            return 0;
        }
    }
    

    BusinessAccount类:

    @Entity
    @Table(name = "business_account")
    public class BusinessAccount extends Model {
    
        @Id
        public Long id;
    
        public String portal;
        public String region;
        public String category;
        public String hqCountry;
        public String portalCountry;
    
        @OneToMany(mappedBy = "businessAccount")
        public List<GaDataModel> gaDataModels;
    }
    

    测试方法:

    @Test
    public void businessAccountTest () {
        FakeApplication app = Helpers.fakeApplication(Helpers.inMemoryDatabase());
        Helpers.start(app);
    
        BusinessAccount ba = new BusinessAccount();
        ba.id=1L;
    
        GaDataModel gd = new GaDataModel("01/01/2014");
        gd.setBusinessAccount(ba);
        ba.gaDataModels.add(gd);
    
        Ebean.save(ba);
        Ebean.save(gd);
    
        BusinessAccount fba = Ebean.find(BusinessAccount.class, 1L);
        GaDataModel fgd = fba.gaDataModels.get(0);
        System.out.println("GaDataModel:  date:"+fgd.gaDataModelPK.date);
    }
    

    注意:您没有在帖子中提供BusinessAccountPK类的代码,因此我将BusinessAccount的ID更改为Long。 但是您可以使此关系与GaDataModel - GaDataModelPK关系相同。或者,如果您更新问题,我可以更新我的答案。