Hibernate how to remove item from list
I have been facing some challenges of understanding how list are 开发者_开发技巧managed in hibernate.
I have looked at the following post: hibernate removing item from a list does not persist but that did not help.
So here is the parent:
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>();
here is the child
public class MaterialAttribute extends MappedModel implements Serializable
{
/**
* identifies the material that these attributes are associated with
*/
@ManyToOne
@JoinColumn(name = "material_id", nullable=false, updatable=false, insertable=false)
private Material material;
So in my Service class I am doing the following:
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);
}
So with the above set up the first time everything is created in the database correctly. The second time, my expectation was that the the first set of items in the collection would of been removed and only the new items would be in the database. That did not happen. The original items in the child are there along with the the new items and that that the seq number start at 0 again.
Also, I am seeing the following error
org.hibernate.HibernateException: A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance:
What am I missing.
Implementation of DELETE_ORPHAN
applies some restrictions on operations with collection. In particular, you shouldn't replace that collection with another instance of collection. Add new items to the existing collection instead:
material.getMaterialAttributes().clear();
...
material.getMaterialAttributes().addAll(attribs);
精彩评论