@OrderColumn в Hibernate / JPA приводит к избыточному оператору SQL UPDATE - PullRequest
0 голосов
/ 11 декабря 2018

У меня есть простые двунаправленные отношения между родителями и детьми, когда дети находятся в упорядоченном списке.

Родитель:

@Entity
@Table(name = "Parent")
public class Parent {
    @Id
    private String name;

    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
    @OrderColumn(name = "childIndex")
    private final List<Child> children = new ArrayList<>();

    public void setName(final String name) {
        this.name = name;
    }

    public void addChild(final Child child) {
        this.children.add(child);
    }
}

Дочерний объект:

@Entity
@Table(name = "Child")
public class Child {

    @Id
    @GeneratedValue(generator = "hibernate-uuid")
    @GenericGenerator(name = "hibernate-uuid", strategy = "uuid2")
    private String id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "parentName")
    private Parent parent;

    Child() {}

    public Child(final Parent parent) {
        this.parent = parent;
    }
}

Я добавляю экземпляр Parent и Child следующим образом:

SessionFactory sessionFactory = ...
try (Session session = sessionFactory.openSession()) {
    session.beginTransaction();

    Parent parent = new Parent();
    parent.setName("SomeName");
    Child child = new Child(parent);
    parent.addChild(child);

    session.merge(parent);

    session.getTransaction()
            .commit();
}

Это работает нормально и приводит к следующему SQL:

Hibernate: select parent0_.name as name1_1_1_, children1_.parentName as parentNa2_0_3_, children1_.id as id1_0_3_, children1_.itemIndex as itemInde3_3_, children1_.id as id1_0_0_, children1_.parentName as parentNa2_0_0_ from Parent parent0_ left outer join Child children1_ on parent0_.name=children1_.parentName where parent0_.name=?
Hibernate: insert into Parent (name) values (?)
Hibernate: insert into Child (parentName, id) values (?, ?)
Hibernate: update Child set itemIndex=? where id=?

Возможно ли этоудалить оператор UPDATE и вместо него установить childIndex при вставке строки Child?

Я пытался установить nullable=false для аннотации OrderColumn, но это привело к null value in column "childindex" violates not-null constraintошибка, поскольку Hibernate все еще пытается вставить столбец Child без установки childindex.

Заранее спасибо!

Редактировать:

По предложению Мика, я явнодобавил атрибут childIndex к объекту Child, например:

@Column(nullable = false)
private int childIndex;

Хотя это приводит к тому, что столбец становится ненулевым, он не удаляет дополнительный оператор UPDATE.С этим изменением Hibernate, по-видимому, устанавливает childIndex в 0 для INSERT (независимо от того, каким индексом на самом деле является дочерний элемент; я проверял это путем добавления дополнительных дочерних элементов), а затем выполняет UPDATE для исправления индекса.Я предполагаю, что Hibernate просто использует любое значение в дочернем объекте, которое по умолчанию равно 0, а затем обновляет его после завершения INSERT, даже если это правильное значение.

1 Ответ

0 голосов
/ 12 декабря 2018

хорошо, похоже, что Hibernate делает здесь немного магии, когда вы объединяете родительскую сущность.Кажется, можно сделать вывод, что у дочерней сущности должен быть дополнительный атрибут - но этот факт обнаруживается ленивым - отсюда и ваше двойное ОБНОВЛЕНИЕ.Что если вы также явно определили правильный атрибут childIndex для дочерней сущности?Эта аннотация @Column была бы подходящим местом для аннотирования ваших требований, допускающих допускаемые значения.Также это должно заставить Hibernate сразу вставить значение с первым оператором UPDATE.

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