Hibernate как удалить элемент из списка - PullRequest
1 голос
/ 24 марта 2011

Я столкнулся с некоторыми проблемами в понимании того, как управлять списком в спящем режиме.

Я посмотрел следующее сообщение: Спящий режим, удаление элемента из списка не сохраняется , но это не помогло.

Так вот родитель:

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, реализует Сериализуемый

{
    /**
     * identifies the material that these attributes are associated with
     */
    @ManyToOne
    @JoinColumn(name = "material_id", nullable=false, updatable=false, insertable=false)
    private Material material;

Итак, в классе обслуживания я делаю следующее:

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" больше не упоминалась экземпляром объекта-владельца:

Чего мне не хватает.

1 Ответ

4 голосов
/ 24 марта 2011

Реализация DELETE_ORPHAN накладывает некоторые ограничения на операции со сбором. В частности, вы не должны заменять эту коллекцию другим экземпляром коллекции. Вместо этого добавьте новые элементы в существующую коллекцию:

material.getMaterialAttributes().clear();
... 
material.getMaterialAttributes().addAll(attribs); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...