Ebean部分没有保存ManyToOne关联



序言

我正在努力解决一个非常奇怪的问题。我正试图创建一个";web应用程序助推器";过程-运行应用程序,填写初始数据库,进行一些增强,并准备好提供服务。

我有一张桌子,上面有40000多张Stuff唱片。我有一张表格,里面有一万多条教学记录。

每个物品都有说明->填充指令是多对一的关系。

我的应用程序启动步骤是:

  1. 填写填充项,但不要初始化它们的说明
  2. 填写所有说明
  3. 试着把东西和说明书联系起来

现在我如何做第三步:

public class AssociateJob {
//TODO - !! there are some gaps in processing! Why??
private static final int PAGE_SIZE = 100;
/**
 * Best effort to associate stuff and instructions
 *
 * @return count of orphaned (instruction == null) stuffs
 */
public int associate() {
    PagingList<Stuff> stuffs = Stuff.find.findPagingList(PAGE_SIZE);
    return processPagingList(stuffs);
}

private int processPagingList(PagingList<Stuff> pages) {
    int countNull = 0;
    for (int page = 0; page < pages.getTotalPageCount(); page++) {
        Page<Stuff> stuffsPage = pages.getPage(page);
        countNull += processPage(stuffsPage);
    }
    return countNull;
}
private int processPage(Page<Stuff> stuffsPage) {
    List<Stuff> list = stuffsPage.getList();
    return processList(list);
}
private int processList(List<Stuff> list) {
    int countNull = 0;
    EbeanServer server = Ebean.getServer(null);
    Transaction tx = beginTransaction();
    Set<String> fields = new HashSet<>();
    fields.add("instruction");
    for (Stuff d : list) {
        Instruction i = Instruction.byNameAndForm(d.name, d.form);
        if (i == null) {
            countNull++;
            continue;
        }
        d.instruction = i;
        server.update(d, fields, tx);
    }
    commit(tx);
    return countNull;
}

private Transaction beginTransaction() {
    EbeanServer server = Ebean.getServer(null);
    Transaction transaction = server.beginTransaction();
    transaction.setBatchSize(100);
    transaction.setPersistCascade(false);
    return transaction;
}
private void commit(Transaction transaction) {
    transaction.commit();
}

}

步骤3完成时,AssociateJob.associate()方法返回6-6个没有指令的填充项,所以我以后必须手动指定它。

问题

事实上,有许多关联未保存。当我执行:

int countNull = Stuff.find.where().eq("instruction", null).findRowCount();

我在没有指示的情况下收到了超过12000个的物品。

问题

为什么会发生这种情况?我该如何解决?

目前,我坚持使用一种临时的解决方法(创建另一个作业来将东西与stuff.instruction == null关联),但这非常糟糕,这个可能是Ebean的问题将影响我未来的内部流程。

多亏了Rob的提示,我找到了一个非常简单优雅的问题解决方案:

public class AssociateJob {

    public int associate() {
        String sql = 
           "UPDATE stuff AS s SET instruction_id = " + 
           "(SELECT i.id FROM instruction AS i WHERE " + 
           "i.name LIKE s.name AND i.form LIKE s.form )" +
           " WHERE instruction_id IS NULL";
        SqlUpdate update = Ebean.createSqlUpdate(sql);
        return update.execute();
    }

}

因此,整个批处理可以通过一个大型更新操作来完成,这是我没有想到的,因为ORM的面向对象方法很优雅。

最新更新