我按照https://vladmihalcea.com/the-best-way-to-map-a-onetomany-association-with-jpa-and-hibernate/映射一对多关系
但是我遇到了删除孤儿的问题。
我被关注了 其他答案
为孩子设置父母为空,但我没有孩子将其父母设置为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
,这将执行单个查询然后
或任何其他解决方案?