【问题标题】:orphan removal is deleting all previous records when I persist new data当我保留新数据时,孤儿删除正在删除所有以前的记录
【发布时间】:2018-07-02 01:02:21
【问题描述】:

我正在使用休眠 orphanRemoval 来管理子记录的删除。 例如,有一个实体 Fp 与子实体 Ledger

    @OneToMany(fetch=FetchType.LAZY,cascade = CascadeType.ALL, orphanRemoval = true, mappedBy="fp")
    public Set<Ledger> getLedgers() {
        return this.ledgers;
    }

通常 Fp 会获取被编辑的分类帐 set,如果不再需要记录,则将其从 set 中删除,然后Fp 被持久化时将从数据库中删除。

这种方法还有另一个'副作用',当我想添加新记录而不必打扰以前的数据时。之前的所有数据都会被删除。

我创建一个新的 set 分类帐并将该组添加到 Fp 然后保存 Fp

LinkedHashSet<Ledger> genLedgerAccSet = new LinkedHashSet<>();

Ledger expenseLedger = new Ledger();
expenseLedger.setChartaccountByAccCode(accCode);
expenseLedger.setCreateDate(selectedFp.getYearEnd());
expenseLedger.setCurrency(defaultCurr);                         
expenseLedger.setTxnDate(new Date());
expenseLedger.setFp(fp);                                    
expenseLedger.setDebitAmt(0);
expenseLedger.setCreditAmt(expBalDiff);                                  
genLedgerAccSet.add(expenseLedger);

Ledger expenseLedger2 = new Ledger();
expenseLedger2.setChartaccountByAccCode(accCode2);
expenseLedger2.setCreateDate(selectedFp.getYearEnd());
expenseLedger2.setCurrency(defaultCurr);                         
expenseLedger2.setTxnDate(new Date());
expenseLedger2.setFp(fp);                                    
expenseLedger2.setDebitAmt(0);
expenseLedger2.setCreditAmt(expBalDiff);                                  
genLedgerAccSet.add(expenseLedger2);

fp.setLedgers(genLedgerAccSet);
financialperiodService.update(fp);
//the service implements a method from DAO to merge
final T savedEntity = (T) sessionFactory.getCurrentSession().merge(entity);

我的猜测是即使我还没有拿到它,新的集合也会替换旧的集合。 我正在使用休眠 4.2.4.Final

有没有更好的方法将更多数据添加到 Fp 的子记录中,而不会最终删除所有以前的记录

【问题讨论】:

    标签: java hibernate one-to-many


    【解决方案1】:

    您正在覆盖 Fp 对象中的分类帐,这就是您删除子对象的原因。您需要从 Fp 对象中获取分类帐,然后保存新的分类帐。

    获取对分类帐的引用:

    Set<Ledger> genLedgerAccSet = fp.getLedgers();
    

    创建新分类帐:

    Ledger expenseLedger = new Ledger();
    expenseLedger.setChartaccountByAccCode(accCode);
    expenseLedger.setCreateDate(selectedFp.getYearEnd());
    expenseLedger.setCurrency(defaultCurr);                         
    expenseLedger.setTxnDate(new Date());
    expenseLedger.setFp(fp);                                    
    expenseLedger.setDebitAmt(0);
    expenseLedger.setCreditAmt(expBalDiff);                                  
    
    genLedgerAccSet.add(expenseLedger);
    
    expenseLedgerService.save(expenseLedger);
    

    我猜 expenseLedgerService 是您保存分类帐的地方。

    【讨论】:

    • 嗨,我添加了多个分类帐,因此我使用 Fp 集。我试图避免先获取 Fp 分类帐,然后在保存之前将新分类帐添加到其中,因为这将成为性能障碍,因为它会获取整个表(这是巨大的)。如果我必须使用 expenseLedgerService 进行保存,这意味着循环遍历新分类帐,一次保存一个
    • 因为你设置了 FetchType.LAZY 你的 Set 不会被加载,它会被代理。您必须获取分类帐并将它们添加到集合中。如果您需要保存多个分类帐,请使用批量插入。
    猜你喜欢
    • 2014-10-07
    • 2013-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-02
    • 2012-10-22
    • 2018-07-26
    相关资源
    最近更新 更多