1

我按照https://vladmihalcea.com/the-best-way-to-map-a-onetomany-association-with-jpa-and-hibernate/映射一对多关系

但是我遇到了删除孤儿的问题。
我被关注了 其他答案

  1. https://stackoverflow.com/a/10427536/3425489
  2. https://stackoverflow.com/a/3071125/3425489

为孩子设置父母为,但我没有孩子将其父母设置为null

我正在使用Session#saveOrUpdate特定的休眠模式,在 DB 中我有3 个孩子,从视图中我有2 个孩子要更新并想要删除第三个或最后一个,如何处理这种情况?

我的代码片段如下:

实体类 SRS

@Entity
@Table(name="srs")
public class SRS implements Serializable {
    [...]

    @OneToMany( mappedBy="srs"/*, cascade=CascadeType.ALL*/, orphanRemoval=true )
    @Cascade(value={CascadeType.SAVE_UPDATE, CascadeType.REMOVE, CascadeType.REFRESH, CascadeType.MERGE})
    private List<SrsRequirement> srsRequirements = new ArrayList<>();

    public void addRequirement( SrsRequirement srsRequirement ) {
        this.srsRequirements.add( srsRequirement );
        srsRequirement.setSrs( this );
    }
    public void  removeRequirement( SrsRequirement srsRequirement ) {
        this.srsRequirements.remove( srsRequirement );
        srsRequirement.setSrs( null );
    }

    [...]
}

实体类 SrsRequirement

@Entity
@Table( name="srs_requirement" )
public class SrsRequirement implements Serializable {

    [...]

    @ManyToOne( fetch=FetchType.LAZY )
    @JoinColumn( name="srs_id" )
    private SRS srs;

    [...]

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        SrsRequirement other = (SrsRequirement) obj;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        return true;
    }
}

从 DAO 保存和更新的代码

@Override
public boolean saveOrUpdateSRS( SRS srs ) {
    Session session = null;
    Transaction transaction = null;
    boolean isSaved = false;
    List<SrsRequirement> srsRequirements = srs.getSrsRequirements();
    try {
        session = getSession();
        transaction = session.beginTransaction();
        session.saveOrUpdate( srs );
        session.flush();
        srs.setSrsRequirements( session.get( SRS.class, srs.getId() ).getSrsRequirements() );
        for( SrsRequirement srsRequirement : srs.getSrsRequirements() ) {
            System.out.println( srsRequirement.toString() );
            if( !srsRequirements.contains( srsRequirement ) )
                srs.removeRequirement( srsRequirement );
        }
        if( transaction!= null && transaction.getStatus().equals(TransactionStatus.ACTIVE) )
            transaction.commit();
        isSaved = true;
    } catch ( Exception ex ) {

    } finally{

    }
    return isSaved;
}

更新
我已经解决了这个问题session.clear(),然后session.load(),然后让所有人requirements检查它们,然后删除孤儿。

以下是工作代码片段

session = getSession();
transaction = session.beginTransaction();
session.saveOrUpdate( srs );
session.flush();session.clear();
srs = session.load( SRS.class, srs.getId() );
for( Iterator<SrsRequirement> iterator = srs.getSrsRequirements().iterator(); iterator.hasNext(); ) {
    SrsRequirement srsRequirement = iterator.next();
//          System.out.println( srsRequirement.toString() );
    if( !srsRequirements.contains( srsRequirement ) ) {
//              srs.removeRequirement( srsRequirement );
        iterator.remove();
        srsRequirement.setSrs( null );
    }
}

但是这段代码的问题是它发出了多个选择语句,应该优化

我应该执行单独HQL的查询以删除其余部分,而不是这样做srsRequirements,这将执行单个查询然后
或任何其他解决方案?

4

0 回答 0