Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > Update коллекции в Hibernate


Автор: NiUb 6.2.2010, 14:35
Здравствуйте,
Я столкнулся с такой проблемой, у меня есть объект Product, в нем есть ArrayList объектов Features, промэпленный как @OneToMany(fetch = FetchType.EAGER,cascade = CascadeType.ALL ),Объект Feature c Product никак не связан, то есть связь однонаправленная
Хибернайт создаёт таблицу ассоциаций product_feature в которой сопоставляет праймари ключи из обеих таблиц
При сохранении путём
Код

getHibernateTemplate().save(product);
 
Всё сохраняется нормально, но при апдейте данных путём
Код

getHibernateTemplate().update(product);

Возникает следующая проблема - коллекция Features в таблице Features переписывается заново, то есть если в Features были такие днные: 1 2 3 4 , то при добавлении к Fetures нового элемента (пусть будет 5) и апдейта Product в базе теперь будет  1 2 3 4 1 2 3 4 5 , то есть данные чего то дублируются
Если вместо 4 вписать 5 и проардейтить Product то в таблице будет 1 2 3 4 1 2 3 5
При этом в таблице соответствий (product_feature) каждый раз при апдейте одному и тому же уже сохранённому Product ставится в соответствие новая коллекция
Почему так происходит? Помогите,пожалуйста, разобраться 
Заранее благодарен за помощь

Автор: AntonSaburov 6.2.2010, 18:59
Объекты никак не связаны - это как-то непонятно. Лучше тогда уж код привести. И таблицы.


Автор: afon 6.2.2010, 19:12
А как вы получается список Features у продукта? 

СКорее всего нужно делать не просто 
product.setFeatures(List<Features>)

а вот так: 
product.getFeatures().add(feature)

Второй вариант, отсутствие обратной связи.

Третий вариант, работайте со списком Features безотносительно родителя Product, они же у вас ничего о свеом продукте не знают. 
List<Features> featuresOfProduct = product.getFeatures();
Теперь работаем с фичами с каждой по отдельности. Кого-то убили, кого-то созранили путем feature.setProduct(product), getHT().save(feature, feature.getClass()).
В следующий раз, когда вы подтянете свой product.getFeatures() - новые фичи будут в списке, а старых не будет.

Автор: NiUb 6.2.2010, 19:17
mapping of product
Код

@Entity
public class Product {

    public Product() {
    }


    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;


    public Long getId() {
        return this.id;
    }

  
    public void setId(Long id) {
        this.id = id;
    }


    private String name;


    public String getName() {
        return this.name;
    }


    public void setName(String name) {
        this.name = name;
    }
    
    @OneToMany(fetch = FetchType.EAGER,cascade = CascadeType.ALL )
   

    private List<Feature> features;

    public List<Feature> getFeatures() {
        return this.features;
    }

    public void setFeatures(List<Feature> features) {
        this.features = features;
    }
}

mapping of Feature
Код

@Entity
public class Feature {
    
    public Feature() {
    }


    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;

    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    private String title;

    public String getTitle() {
        return this.title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    private String enumerations;

    public String getEnumerations() {
        return enumerations;
    }

    public void setEnumerations(String enumerations) {
        this.enumerations = enumerations;
    }
    
}


Сохраняю
Код

public void addProduct(Product product) 
    {
     getHibernateTemplate().save(product);
        
    }


Обновляю
Код

public void updateProduct(Product product) {
        getHibernateTemplate().update(product);
    }


Добавлено через 9 минут и 34 секунды
Цитата(afon @ 6.2.2010,  19:12)
А как вы получается список Features у продукта? 

Product у меня представляет собой command object в модели MVC , List Features заполняется из формы после чего в onSubmit() контроллера вызывается привелдённый выше метод обновления продукта
Я бы даже не заметил этой проблемы если бы случайно не полез смотреть базу руками...

Автор: NiUb 6.2.2010, 19:54
Table product_feature
Product_id Feature_id
67;            73
67;            74
67;            75
67;            76

Table feature
Feature_id   Служебные String
69;            "222";"222"
70;            "222";"222"
71;            "222";"222"
72;            "222";"222"
73;            "222";"222"
74;            "222";"222"
75;            "222";"222"
76;            "222";"222"

Сначала я сохранил продукт c id 67 c листом feature c id 69 70 71 72 
Затем я просто вызвал getHibernateTemplate().update(product); после чего 
прежняя коллекция была "отвязана" от моего продукта (но в базе осталась)
вместо неё была создана новая - с id 73 74 75 76 т привязана к старому продукту с id 67,
что и видно по таблице product_feature

Автор: garbuz 8.2.2010, 14:48
Насколько я понял вы используете Spring MVC.
Покажите метод formBackingObject. Уверены что правильно получаете объект для редактирования?

Автор: NiUb 9.2.2010, 18:53
Нашёл причину трабла
Каждый раз при обновлении в коде чего то создавалась новая коллекция, нужно было просто чуть глубже капнуть (код не мой поэтому я и не в курсе был)
Теперь получаю старую коллекцию и апдейтю её, всё работает
Всем СПАСИБО за отклики и советы

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)