Hibernate - Операция обновления: - PullRequest
1 голос
/ 15 июня 2011
@Entity
@Table(name="Student")
public class Student {

    private String id;
    private String firstName;
    private String lastName;
    private Set<Grade> grades = new HashSet<Grade>();

public void addGrade(Grade grade){
        grades.add(grade);
    }
    //rest of Getters and setters omitted

    public void removeGrade(Grade grade){
    grades.remove(grade);
    }
@OneToMany(cascade = CascadeType.ALL,fetch=FetchType.LAZY,orphanRemoval=true)
    @JoinColumn(name="s_id")
    public Set<Grade> getGrades() {
        return grades;
    }

Оценка: * * 1002

@Entity
@Table(name="Grade")
public class Grade {
//all omitted
}

У меня есть объект ученик, и я хотел бы удалить одну существующую оценку из коллекции оценок ученика с идентификатором 'xyz'

Я делаю следующее:

String id = "xyz";
Session session = sessionFactory.getCurrentSession();
    Student student = (Student)session.load(Student.class,id);
        student.removeGrade(grade);
        session.update(student);

Все работает без нареканий, но в SQL-запросах я вижу странное обновление:

Hibernate: select student0_.id as id0_0_, student0_.FirstName as FirstName0_0_, student0_.LASTNAME as LASTNAME0_0_ from Student student0_ where student0_.id=?
Hibernate: select grades0_.s_id as s4_0_1_, grades0_.id as id1_, grades0_.id as id1_0_, grades0_.FirstQuestion as FirstQue2_1_0_, grades0_.TotalGrade as TotalGrade1_0_ from Grade grades0_ where grades0_.s_id=?
Hibernate: update Grade set s_id=null where s_id=? and id=?
Hibernate: delete from Grade where id=?

Почему у меня обновление? update Grade set s_id=null where s_id=? and id=?

Как я могу пропустить это, чтобы увеличить производительность?

1 Ответ

1 голос
/ 15 июня 2011

Это кажется ненужным, и это в вашем случае, потому что ваш каскадный тип ВСЕ.Тем не менее, существуют некоторые модели данных, в которых ребенку может быть целесообразно существовать независимо от отношения ко многим другой сущности.Другими словами, обновление имеет смысл, если вы не хотите удалять оценку, если вы нарушаете отношения между студентом и оценкой.В этом случае hibernate должен просто обнулить значение внешнего ключа, но не удалять строку оценки.

Так вот что происходит - когда вы явно разрываете связь, удаляя дочерний элемент из коллекции на родительском объекте, hibernate знает, как обновить дочернюю таблицу для удаления внешнего ключа.Когда ваш каскадный параметр настроен с параметром «ВСЕ» (на самом деле это, вероятно, orphanRemoval = true), hibernate знает, как удалить фактическую дочернюю строку, когда у нее больше нет родителя.Я подозреваю, что hibernate не оптимизирован так, что он распознает, когда можно просто удалить.

Вероятно, это была оптимизация, которую они просто решили не реализовывать.

О производительности коллекции вы можете прочитать здесь .Особенно раздел 19.5.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...