0

考虑以下实体模型:

档案实体。

@Entity
@Table(name = "dossiers", uniqueConstraints = @UniqueConstraint(columnNames = { "site_id", "dossier_id" }))
@Audited(withModifiedFlag = true)
@Access(AccessType.FIELD)
public final class Dossier extends EntityObject {

    @Column(name = "name", nullable = false, length = 255)
    private String name;

    @OneToOne(fetch = FetchType.EAGER, mappedBy = "dossier", optional = true, cascade = CascadeType.ALL, orphanRemoval = true)
private Commission commission;

}

佣金实体。

@Entity
@Table(name = "commissions")
@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
@Access(AccessType.FIELD)
public class Commission extends EntityObject{

    @Column(name = "name")
    private String name;

    @OneToMany(mappedBy = "commission", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
    @OrderBy(clause = "boundary ASC NULLS LAST")
    private List<CommissionBracket> commissionBrackets;

    @OneToOne(optional = true)
    @JoinColumn(name = "dossier_id", nullable = true)
    private Dossier dossier;

}

括号实体。

@Entity
@Table(name = "commission_brackets")
@Access(AccessType.FIELD)
public class CommissionBracket extends EntityObject {

    @ManyToOne(optional = false)
    @JoinColumn(name = "commission_id")
    private Commission commission;

    @Column(name = "boundary")
    private Integer boundary;
}

现在,当我想从档案中替换佣金时。我必须这样做:

    boolean notSaved = true;
    if(domain.getCommission() != null) {
        toSave.setCommission(domain.getCommission());
        toSave.getCommission().getCommissionBrackets().clear();
        toSave = dossierRepository.save(toSave);
        toSave.setCommission(null);
        toSave = dossierRepository.save(toSave);
        notSaved = false;
    }
    if(dossier.getCommission() != null) {
        final Commission newCommission = commissionRepository.save(dossier.getCommission());
        toSave.setCommission(newCommission);
        toSave = dossierRepository.save(toSave);
        notSaved = false;
    }
    if(notSaved) {
        toSave = dossierRepository.save(toSave);
    }

请注意,存储库上的保存操作会根据传递的对象是否设置了其 id 来执行持久化或合并。

而一个头脑清醒的正常人会认为他可以简单地做到:

dossier.setCommission(newCommission);
dossierRepository.save(newCommission);

出于某种原因,无论佣金是否附有括号,我都需要:

  1. 清除现有佣金的括号
  2. 节省
  3. 删除现有的佣金
  4. 节省
  5. 坚持新的佣金
  6. 在档案中设置新的佣金
  7. 节省

跳过任何步骤都会导致此错误:

拥有实体实例不再引用具有 cascade="all-delete-orphan" 的集合:Commission.commissionBrackets

虽然对此可能有一个合理的解释,但它感觉非常难看,也许有一种更清洁的方法来做到这一点?除了删除现有的佣金,我还可以完全更新它,但这不会反映功能现实。

使用的休眠版本是:4.3.10。使用的最终数据库:postgres 9.4.4.1

所以我的问题是。我做得对还是在某处有所改进?

4

1 回答 1

0

您没有发布所有相关的实体详细信息,例如Commission与 的关系Dossier,但mappedBy说它在那里。由于与(并且恰好是关系的拥有方)Dossier具有双向关系,因此您只需要维护双方即可。这应该有效:CommissionCommission

// break the current relation, should cause old commissions object to be deleted
dossier.getCommission().setDossier(null);
newCommission.setDossier(dossier);
dossier.setCommission(newCommission);
dossierRepository.save(dossier);
于 2015-11-24T10:04:43.877 回答