2016-01-25 4 views
0

Мне приходится иметь дело с циклическими зависимыми отношениями, на которые я не могу влиять, и я довольно новичок в JPA.Сохраняющиеся циклически зависимые объекты

Так Entity есть члены одного и то же лицо, и я решил, что с помощью:

@Entity 
@Table("A") 
public class A { 
    @ManyToMany 
    @JoinTable(name = "A_HAS_SUBAS", 
     joinColumns = {@JoinColumn(name = "A_ID")}, 
     inverseJoinColumns = {@JoinColumn(name = "SUBA_ID")}) 
    private Set<A> as; 
} 

При записи в БД У меня есть проблема, что Hibernate, кажется, не знает, где А должно быть сохранено первым. Я попытался решить эту проблему, удалив все отношения из A, записывая в БД и восстанавливая отношения впоследствии через спящий режим.

Это похоже на работу, но, похоже, не работает, если A не имеет SubAs, и это не соответствует моему пониманию проблемы. Поэтому я, конечно, ошибаюсь.

Платформа Entity без отношений сохраняется на внутренней сделки:

@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW) 
private void immediatelySaveNewEntity(A entity) { 
    try { 
     if (!dao.entityExistsFromId((int) entity.getId())) { dao.save(entity); } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

В результате я получаю

ORA-02291: целостность ограничение (...) нарушается - родительский ключ не найдено

Я могу обойти эту проблему, удалив ограничения из БД, но это не мой предпочтительный способ справиться с этим.

ответ

0

Ну, это было для меня раздумья, но мой подход был в порядке с небольшой ошибкой.

У меня были связанные с циклом сущности. Перед записью в БД я удалил все отношения из объекта, сохранил его в БД и впоследствии восстановил отношения в качестве обновления. Это было хорошо, потому что таким образом я имел все сущности в БД и мог легко восстановить циклические зависимости. Хотелось бы, чтобы я избавился от них в первую очередь, но нет.

Ошибка была как Я сделал это. Имея единую транзакцию, удаление отношений не имело никакого эффекта, потому что, когда Сущность со всеми ее отношениями окончательно сохранилась в БД, я уже восстановил прежнее состояние. я попытался использовать новую транзакцию с

@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW) 

, но в то же Bean и, как я узнал на своей шкуре ту же операцию. Подсказка: Strange behaviour with @Transactional(propagation=Propagation.REQUIRES_NEW)

Итак, я ввел новый экземпляр одного и того же компонента и выполнил новую транзакцию в этом экземпляре, с доступом к прокси и хорошо - сработал.

0

Я не вижу никакого @Id атрибут, объявленный в классе A. Я считаю, что вы, возможно, удалили его для краткости.

Вы можете попробовать обновить @ManyToMany до @ManyToMany(cascade=CascadeType.ALL), как показано ниже, и попробуйте.

@Entity 
@Table("A") 
public class A { 
    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private int id; 

    @ManyToMany(cascade=CascadeType.ALL) 
    @JoinTable(name = "A_HAS_SUBAS", 
      joinColumns = {@JoinColumn(name = "A_ID")}, 
      inverseJoinColumns = {@JoinColumn(name = "SUBA_ID")}) 
    public Set<A> as; 
} 

Способный сохранить его с нижестоящим тестовым кодом спящего режима и также работать с JPA.

Session sess = //Get Session 
Transaction tx1 = sess.beginTransaction(); 

A a = new A(); 
a.as = new HashSet<>(); 
a.as.add(new A()); 
a.as.add(new A()); 
sess.persist(a); 
tx1.commit(); 

Incase Я неправильно понял ваш тестовый сценарий, чтобы облегчить отправку основного тестового сценария.

Смежные вопросы