我一直面临着理解如何在hibernate中管理列表的一些挑战。
我查看过以下帖子:hibernate removing item from a list does not persist但这没有帮助。
所以这是父母:
public class Material extends MappedModel implements Serializable
{
/**
* List of material attributes associated with the given material
*/
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
@JoinColumn(name = "material_id", nullable = false)
@org.hibernate.annotations.IndexColumn(name = "seq_number", base = 0)
private List<MaterialAttribute> materialAttributes = new ArrayList<MaterialAttribute>();
这是孩子
公共类MaterialAttribute扩展MappedModel实现Serializable
{
/**
* identifies the material that these attributes are associated with
*/
@ManyToOne
@JoinColumn(name = "material_id", nullable=false, updatable=false, insertable=false)
private Material material;
所以在我的Service类中,我正在执行以下操作:
public void save(MaterialCommand pCmd)
{
Material material = new Material();
if(null != pCmd.getMaterialId())
{
material = this.loadMaterial(pCmd.getMaterialId());
}
material.setName(pCmd.getName());
material.getMaterialAttributes().clear();
List<MaterialAttribute> attribs = new ArrayList<MaterialAttribute>();
if(CollectionUtils.isNotEmpty(pCmd.getAttribs()))
{
Iterator<MaterialAttributeCommand> iter = pCmd.getAttribs().iterator();
while(iter.hasNext())
{
MaterialAttributeCommand attribCmd = (MaterialAttributeCommand) iter.next();
if (StringUtils.isNotBlank(attribCmd.getDisplayName()))
{
MaterialAttribute attrib = new MaterialAttribute();
attrib.setDisplayName(attribCmd.getDisplayName());
attrib.setValidationType(null);
attribs.add(attrib);
}
}
}
material.setMaterialAttributes(attribs);
this.getMaterialDao().update(material);
}
所以通过上面的设置,第一次正确地在数据库中创建了所有内容。第二次,我的期望是集合中的第一组项目将被删除,只有新项目将在数据库中。那没发生。子项中的原始项目与新项目一起存在,并且seq编号从0再次开始。
另外,我看到以下错误
org.hibernate.HibernateException:拥有实体实例不再引用cascade =“all-delete-orphan”的集合:
我错过了什么。
答案 0 :(得分:4)
DELETE_ORPHAN
的实施对集合操作应用了一些限制。特别是,您不应该将该集合替换为另一个集合实例。而是将新项目添加到现有集合中:
material.getMaterialAttributes().clear();
...
material.getMaterialAttributes().addAll(attribs);