CascadeType.Persist не работает с таблицей типов генератора первичных ключей в JPA - PullRequest
3 голосов
/ 21 ноября 2011

У меня проблема с использованием CascadeType.Persist для моего JPA / автономного проекта.У меня есть родительская сущность, которая имеет список дочерних сущностей, которые должны быть сохранены вместе с родителем, а первичный ключ родительского объекта генерируется с использованием таблицы (GeneratorType.TABLE), и я использую таблицу для генерации первичного ключа.

В родительском у меня есть:

    @OneToMany(mappedBy="parent",fetch=FetchType.EAGER,cascade= {CascadeType.PERSIST,CascadeType.DETACH})
    List<Child> children;
    //Getter and Setter

    @PostPersist
    public void setParentID(){
    System.out.println("Inside Postpersist");
    for(Child ch : this.children){
        ch.setParent(this);
                    System.out.println(ch.getParent().getParentId());
    }
}

В дочернем:

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

В БД у меня установлен ненулевой столбец Parent_ID родительской таблицы.Когда я сохраняю сущность Parent, и для нее задан список дочерних сущностей, он выдает

    ConstraintViolationException: Cannot insert the value NULL into column 'Parent_ID', table 'jpaTest.Child', column does not allow nulls.

, поскольку Parent является нулевым для всех дочерних сущностей, хотя он печатает набор ParentId для каждой дочерней сущностиметод, аннотированный @PostPersist

Однако этого не происходит, и постоянство родительского и дочернего элементов имеет место, когда я меняю стратегию генерации первичного ключа с типа TABLE на AUTO.Как и почему это происходит.

Поставщик - Hibernate.И мой сервер БД mssql.

Ответы [ 3 ]

2 голосов
/ 21 ноября 2011

Этот подход выглядит немного слабым, потому что спецификация не дает слишком большой поддержки для изменения других объектов в обратных вызовах жизненного цикла:

Как правило, метод жизненного цикла переносимого приложения не должен вызвать операции EntityManager или Query, получить доступ к другому объекту экземпляры, или изменить отношения в пределах той же персистентности контекст.

Кроме того, у вас нет гарантии о порядке каскада для детей и @ PostPersist в родительском элементе:

Это зависит от реализации того, являются ли методы обратного вызова вызывается до или после каскадирования событий жизненного цикла в связанные лица. Приложения не должны зависеть от этого заказа.

2 голосов
/ 22 ноября 2011

Да, это работало без опускания cascade-persist.Все, что мне нужно было сделать, это установить для родительского объекта значение Child при добавлении дочерних объектов в список потомков в Parent, так как это двунаправленное отношение.

В Parent:

    public void setParentToChild(Child ch){
    if(this.getChildren()==null){
        this.children = new ArrayList<Children>();
    }
            this.children.add(cb);
            //this is what worked. Also set the Parent to Child
    cb.setCustomer(this);
}

Теперь при создании нового Parent и Child я вызываю этот метод для добавления дочернего элемента в parent.А JPA ничего не делает для установки в бизнес-коде.Спасибо вам, ребята.

1 голос
/ 21 ноября 2011

Я предполагаю, что родительское поле дочернего элемента должно быть инициализировано до сохранения родительского поля, а не после, в методе @PostPersist, который, вероятно, вызывается после того, как каскад был выполнен.

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