Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Ebean部分不保存多通关联 序言_Java_Database_Playframework 2.0_Ebean - Fatal编程技术网

Java Ebean部分不保存多通关联 序言

Java Ebean部分不保存多通关联 序言,java,database,playframework-2.0,ebean,Java,Database,Playframework 2.0,Ebean,我正在努力解决一个非常奇怪的问题。 我正在尝试创建一个“web应用程序boostrap”过程—运行应用程序,填充初始数据库,进行一些增强,并准备好提供服务 我有一张有40000多条记录的桌子。 我有一张有10000多条指令记录的表格 每件物品都有说明。->员工指导是一种多方面的关系 我的应用程序启动的步骤包括: 填写填充项,但不要初始化它们的指令 填写所有说明 试着把东西和说明联系起来 现在我如何执行步骤3: public class AssociateJob { //TODO - !! th

我正在努力解决一个非常奇怪的问题。 我正在尝试创建一个“web应用程序boostrap”过程—运行应用程序,填充初始数据库,进行一些增强,并准备好提供服务

我有一张有40000多条记录的桌子。 我有一张有10000多条指令记录的表格

每件物品都有说明。->员工指导是一种多方面的关系

我的应用程序启动的步骤包括:

  • 填写填充项,但不要初始化它们的指令
  • 填写所有说明
  • 试着把东西和说明联系起来
  • 现在我如何执行步骤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();
    }
    
    我收到了超过12000件未经指示的物品

    问题: 为什么会这样?我怎样才能解决它

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

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

    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的面向对象方法的优雅所蒙蔽

    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();
    
        }
    
    
    }