Идентификатор не устанавливается при вызове EntityManager.merge () - PullRequest
9 голосов
/ 01 июня 2011

У меня есть простая связь OneToMany между 2 объектами Parent и Child, как показано ниже.

Parent Entity

    @Entity
    public class Parent {
     @Id
     @GeneratedValue(strategy = GenerationType.AUTO)
     private Long id;
     private String name;
     @Version
     private Long version;

      @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
      List<Child> children = new ArrayList<Child>();

      ....
    }

Child entity

    @Entity
    public class Child {
      @Id
      @GeneratedValue(strategy = GenerationType.AUTO)
      private Long id;
      private String name;
      @Version
      private Long version;
        ...
    }

Ниже приводится мойtest, который загружает существующий родительский элемент, добавляет дочерний элемент и вызывает EntityManager.merge () для родительского элемента.

    @Test
public void testParent(){
    Parent parent = (Parent) dao.loadParent(Parent.class, parentId);

    Child c = new Child();
    c.setName("c");

    parent.getChildren().add(c);

    dao.mergeEntity(parent);

    Assert.assertNotNull(c.getId());
}

Утверждение, в котором проверяется первичный ключ идентификатора, не выполняется.Я вижу, что запись правильно вставлена ​​в базу данных вместе с автоматически назначенным первичным ключом.

Все мои вызовы DAO обернуты вокруг транзакции с распространением в соответствии с требованиями.

Ответы [ 2 ]

13 голосов
/ 01 июня 2011

EntityManager.merge(..) получает экземпляр и возвращает управляемый экземпляр.А в случае переходных случаев он возвращает новый экземпляр (не изменяет исходный)

Так что ваш метод mergeEntity(..) должен return em.merge(entity)

0 голосов
/ 01 июня 2011

Поскольку ваш идентификатор установлен базой данных, JPA / Hibernate может установить его только после того, как оператор SQL был отправлен в базу данных.Если вы сконфигурируете Hibernate для отображения оператора sql или измените журнал на DEBUG, вы, вероятно, увидите, что при вызове mergeEntity.

оператор SQL не выдается. Одним из способов заставить вашу работу теста должно быть добавление em.flush () перед выполнением утверждения для дочернего идентификатора.

Может возникнуть проблема в способе управления транзакцией, но потребуется увидеть код DAO и способ получения ссылки на DAO вваш юнит тест

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