保存多对多时的参照完整性约束违规 - Ebean,Play,Yaml,Tests

时间:2013-12-09 17:33:37

标签: java testing yaml ebean playframework-2.2

我有一个使用Ebean的Play 2.2.1 Java应用程序,我有一个测试环境,用.yml文件创建一个包含初始数据的数据库:

criteria:
  - !!models.Criterion
    name: "testcriterion1"
    id: 10
  - !!models.Criterion
    name: "testcriterion2"
    id: 20

scoringmodels:
  - !!models.ScoringModel
    id: 10
    criteria:
        - !!models.Criterion
            id: 10

模型看起来像这样:

@Entity
public class ScoringModel extends Model {
    @Id
    public Long id;
    @ManyToMany
    public List<Criterion> criteria;
}

@Entity
public class Criterion extends Model {
    @Id
    public Long id;
    @Required
    public String name;
}

在每次测试之前,数据库都会被清除并重建:

@Before
public void createCleanDb() {
    Ebean.execute(Ebean.createCallableSql(dropDdl));
    Ebean.execute(Ebean.createCallableSql(createDdl));
    //Create initial data
    Map<String,List<Object>> all = (Map<String,List<Object>>)Yaml.load("initial-data.yml");
    Ebean.save(all.get("scoringmodels"));
    Ebean.save(all.get("criteria"));
} 

运行测试时出现以下错误:

  

参照完整性约束违规:   “FK_SCORING_MODEL_CRITERION_CR_02:PUBLIC.SCORING_MODEL_CRITERION   FOREIGN KEY(CRITERION_ID)REFERENCES PUBLIC.CRITERION(ID)(10)“; SQL   声明:[错误]插入scoring_model_criterion   (scoring_model_id,criterion_id)值(?,?)[23506-172] [错误]
  在   com.avaje.ebeaninternal.server.persist.ExeUpdateSql.execute(ExeUpdateSql.java:76)   [错误]在   com.avaje.ebeaninternal.server.persist.DefaultPersistExecute.executeSqlUpdate(DefaultPersistExecute.java:115)   [错误]在   com.avaje.ebeaninternal.server.core.PersistRequestUpdateSql.executeNow(PersistRequestUpdateSql.java:44)   [错误]在   com.avaje.ebeaninternal.server.core.PersistRequest.executeStatement(PersistRequest.java:74)   [错误]在   com.avaje.ebeaninternal.server.core.PersistRequestUpdateSql.executeOrQueue(PersistRequestUpdateSql.java:49)   [错误]在   com.avaje.ebeaninternal.server.persist.DefaultPersister.executeSqlUpdate(DefaultPersister.java:139)   [错误]在   com.avaje.ebeaninternal.server.persist.DefaultPersister.saveAssocManyIntersection(DefaultPersister.java:999)   [错误]在   com.avaje.ebeaninternal.server.persist.DefaultPersister.saveMany(DefaultPersister.java:730)   [错误]在   com.avaje.ebeaninternal.server.persist.DefaultPersister.saveAssocMany(DefaultPersister.java:631)   [错误]在   com.avaje.ebeaninternal.server.persist.DefaultPersister.insert(DefaultPersister.java:339)   [错误]在   com.avaje.ebeaninternal.server.persist.DefaultPersister.saveEnhanced(DefaultPersister.java:310)   [错误]在   com.avaje.ebeaninternal.server.persist.DefaultPersister.saveRecurse(DefaultPersister.java:280)   [错误]在   com.avaje.ebeaninternal.server.persist.DefaultPersister.save(DefaultPersister.java:248)   [错误]在   com.avaje.ebeaninternal.server.core.DefaultServer.save(DefaultServer.java:1759)   [错误]在   com.avaje.ebeaninternal.server.core.DefaultServer.save(DefaultServer.java:1737)   [错误]在com.avaje.ebean.Ebean.save(Ebean.java:526)[错误]
  在com.avaje.ebean.Ebean.save(Ebean.java:533)[错误] at   controllers.BaseControllerTest.createCleanDb(BaseControllerTest.java:53)   [错误] ... [错误]引起:org.h2.jdbc.JdbcSQLException:   ReferentielleIntegritätverletzt:“FK_SCORING_MODEL_CRITERION_CR_02:   PUBLIC.SCORING_MODEL_CRITERION FOREIGN KEY(CRITERION_ID)参考   PUBLIC.CRITERION(ID)(10)“

任何提示或答案都会非常感激!

1 个答案:

答案 0 :(得分:2)

所以我通过改变对象持久化的顺序解决了这个问题。作为评分模型参考标准,需要首先插入这些标准。 因此必须是:

@Before
public void createCleanDb() {
    Ebean.execute(Ebean.createCallableSql(dropDdl));
    Ebean.execute(Ebean.createCallableSql(createDdl));
    //Create initial data
    Map<String,List<Object>> all = (Map<String,List<Object>>)Yaml.load("initial-data.yml");
    Ebean.save(all.get("criteria"));
    Ebean.save(all.get("scoringmodels"));
}