Избежание JPA TransientObjectException без сохранения всего вручную

У меня есть иерархия объектов, как это (отклоняя все поля, такие как идентификатор, сеттеры / получатели и т. Д.):

@Entity
class A {
    @OneToOne(cascade=CascadeType.ALL)
    private B b;
}

@Entity
class B {
    @OneToOne(cascade=CascadeType.ALL)
    private A a;

    @OneToOne(cascade=CascadeType.ALL)
    private C c;
}

@Entity
class C {
    private int x;
}

Все лица имеют @Id @GeneratedValue private Long id;

Я использую JPA с Hibernate и MySQL и имею DAO для A который делает простой entityManager.merge(a); entityManager.flush();

Теперь эта конструкция используется в проекте JSF, где я создаю новый A с новым B но значение для C взят из базы данных, следовательно, это существующий объект. Этот недавно заполненный объект отображается на странице и сохраняется только при нажатии кнопки сохранения, поэтому создание и сохранение выполняются в двух разных транзакциях.

Когда я пытаюсь сделать dao.save(a)Я получаю org.hibernate.TransientObjectExceptionне очень удивительно, так как значение для c в классе B уже существует в базе данных.

Теперь актуальный вопрос: могу ли я как-то избежать этой проблемы БЕЗ каскадного сохранения вручную? Я говорю о десятках Bклассы, каждый с десятками Cс - это было бы полностью против моей идеи каскадирования...

Любые идеи приветствуются!

2 ответа

Я обошел проблему, выполнив следующие действия:

В AЯ создал метод List<B> getBs() который получает все й B классов. В BЯ создал метод List<C> getCs(), Теперь в Дао я делаю

public void save(A a) {
    for (B b : a.getBs()) {
        for (C c : b.getCs()) {
            if (c != null) {
                if (c.getId() == null) {
                    entityManager.persist(c);
                } else {
                    entityManager.merge(c);
                }
            }
        }
    }
    super.save(a);
}

Теперь мне нужно только следить за Bс и Cс, но это все же лучше, чем обход всего дерева объектов...

Там может быть проблема из-за аннотации. Вы можете получить помощь из этого примера, чтобы решить вашу проблему.

Другие вопросы по тегам