2013-12-17 1 views
4

класс Studentsaveorupdate() Безразлично не обновляет коллекцию (список) один-ко-многим в спящий режим

public class Student { 

private Long id; 
private String name; 
private String className; 
private List<Phone> phones; 
    // getter setter 
} 

класс Phone

public class Phone { 

private Long id; 
private String number; 
    //getter setter 
    } 

-> mappping файл Student.hbm.xml

 <id name="id" type="long" column="id"> 
     <generator class="native" /> 
    </id> 

    <property name="name" column="name" type="string" /> 

    <property name="className" column="class_name" type="string" /> 

    <list name="phones" cascade="all-delete-orphan"> 
     <key column="student_id"/> 
     <list-index column="idx" /> 
     <one-to-many class="Phone" /> 
    </list> 

-> Файл отображения Phone.hbm.xml

<id name="id" type="long" column="id"> 
     <generator class="native" /> 
    </id> 

    <property name="number" column="number" type="string" /> 

, когда я пытаюсь обновить телефонный номер (список), предыдущая запись не удаляется, но IDX (индекс списка) и внешний ключ является нулевым, а новые записи отмечены правильным idx и внешним ключом! Другие данные (а не список) обновляются полностью точно. Здесь я получаю объект класса из базы данных, изменяю его и передаю объект saveorupdate(), но не помог. Пробовал это так долго. Было бы большой помощью.

код для чтения и обновления:

 private void readAndUpdateStudent() { 
     Student student = null; 
     Session session = HibernateUtil.getSessionFactory().openSession(); 
     String name = "John"; 
     try { 

     String queryString = "from Student student where student.name =:name"; 
     Query query = session.createQuery(queryString); 
     query.setString("name", name); 
     student = (Student) query.uniqueResult(); 
     System.out.println(student.getName()); 
     student.setName("Mary"); 
     List<Phone> phones = new ArrayList<Phone>(); 
     phones.add(new Phone("555555")); //here if I SET rather adding, the already existing values, update is done accordingly 
     phones.add(new Phone("789789"));//but when I use the list as a string type(instead of Phone Type), adding a new 0bject deletes the previous 
     student.setPhones(phones);//entries and adds new list on its own but not in the case of user defined type. 

    } catch (Exception e) {  
     e.printStackTrace(); 
     if (session != null) { 

      session.close(); 

     } 

    }finally{ 

     session.close(); 
     updateStudent(student); 
    } 

} 
private void updateStudent(Student student) { 

    Session session = HibernateUtil.getSessionFactory().openSession(); 
    Transaction tx = null; 

    try { 
     tx = session.beginTransaction(); 
     session.saveOrUpdate(student); 
     tx.commit(); 
    } catch (HibernateException e) { 
     if (tx != null) 
      tx.rollback(); 
     e.printStackTrace(); 
    } finally { 
     session.close(); 
    } 

} 

enter image description here

+0

Вы пытаетесь обновить один телефонный номер (например, изменяя число через сеттер) или вы пытаетесь изменить список телефонных номеров студента? Я подозреваю, что вы меняете список. –

+0

Я использую setter для установки в нем нового списка, например 'student.setPhones (phones)', где телефоны - это новый список –

+0

@anonymous Покажите свой код для обновления телефона. – RAS

ответ

0

Если вы хотите, чтобы обновить список телефонов, вы не должны делать

List<Phone> phones = new ArrayList<Phone>(); 
    phones.add(new Phone("555555")); 
    phones.add(new Phone("789789")); 
    student.setPhones(phones); 

Приведенный выше код не обновите список телефонов, но создайте новый. Чтобы обновить список телефонов, вы должны получить старые списки и обновления своих записей:

List<Phone> phones = student.getPhones(); 
    phones.get(0).setNumber("666666"); 
    phones.get(1).setNumber("888888"); 
    session.saveOrUpdate(student); 
+0

, но когда я использую встроенный тип списка, hibernate обрабатывает все удаление и само обновление. Что случилось с определенными пользователем типами данных? Я ДОЛЖЕН ВСЕ ЭТО ЧЕЛОВЕК! –

+0

Разница заключается в том, что Телефон является сущностью, а String является просто примитивным типом, и поэтому они обрабатываются по-разному –

+0

любым способом, в котором спящий режим управляет собой? –

1

Я заметил, что это немного старо, но FWIW, другой ответ является правильным, вы не должны когда-либо устанавливал новую коллекцию на постоянном объекте, полученном спящим режимом, поскольку это создаст сирот, как это имеет место в вашем случае.

Hibernate проксирует объект, чтобы он мог управлять обновлениями базы данных (какие поля были изменены и т. Д.) Для свойств объекта. Поэтому, когда вы извлекаете объект и устанавливаете новый список, hibernate теряет способность отслеживать изменения для того, что раньше было в этом списке. Поэтому вам следует обновить существующий список, как было указано, поэтому сироты удаляются при обновлении. Вы также можете использовать clear().

List<Phone> phones = student.getPhones(); 
phones.clear(); 
phones.add(new Phone("555555")); 
phones.add(new Phone("789789")); 
session.saveOrUpdate(student); 

Если вы хотите, чтобы избежать дубликатов попробовать набор, а не список, а также осуществлять хэш-код() и Equals() на классе телефона, например, это может иметь смысл проверить проверить равенство на phone.number ,

Надеется, что это помогает :)

Смежные вопросы