При выполнении следующего кода, я получаю org.hibernate.exception.ConstraintViolationException
исключениеorg.hibernate.exception.ConstraintViolationException при использовании нескольких ManyToMany отношений
жаловалась, что
org.h2.jdbc.JdbcSQLException: NULL not allowed for column "SECONDARYELEMENTS_ID";
Я знаю, что это вызвано наличием двух @ManyToMany
отношений от объекта Container до объектов Element. Если я удалю
@ManyToMany(cascade = CascadeType.ALL)
List<Element> secondaryElements;
из класса Container все работает нормально.
Что мне здесь не хватает?
Дайте мне знать, если вам нужна дополнительная информация.
@Transactional
public class JPA2Runner {
//hidding Spring Data JPA repository
@Autowired
ContainerDAO containerDAO;
public boolean run() throws Exception{
Container container1 = new Container();
Container container2 = new Container();
Element element1 = new Element(container1, container2);
Element element2 = new Element(container2, container1);
container1.getPrimaryElements().add(element1);
container1.getSecondaryElements().add(element2);
container2.getPrimaryElements().add(element2);
container2.getSecondaryElements().add(element1);
containerDAO.saveContainer(container1);
return true;
}
}
@Entity
public class Container extends AbstractEntity {
@ManyToMany(cascade = CascadeType.ALL)
List<Element> primaryElements;
@ManyToMany(cascade = CascadeType.ALL)
List<Element> secondaryElements;
public Container(){
primaryElements =new ArrayList<Element>();
secondaryElements = new ArrayList<Element>();
}
}
@Entity
public class Element extends AbstractEntity {
@ManyToOne(cascade = CascadeType.ALL)
private Container dedicatedContainer1;
@ManyToOne(cascade = CascadeType.ALL)
private Container dedicatedContainer2;
public Element(){}
public Element(Container container1, Container container2){
this.dedicatedContainer1 = container1;
this.dedicatedContainer2 = container2;
}
}
Update 1: Может быть, требуется указать @JoinTable в случае, если есть несколько отношения к такому же типу?
Update 2: Благодаря @ducksteps комментариев и подсказки, которые я смог найти обходной путь для этой проблемы. Проблема состоит в том, что приведенное выше определение генерирует присоединиться таблицу с ключами для обоих списков элементов, т.е.
create table Container_Element (Container_id bigint not null, secondaryElements_id bigint not null, primaryElements_id bigint not null)
однако, сохранение контейнер генерирует следующий вставку в соединительной таблице
insert into Container_Element (Container_id, primaryElements_id) values (?, ?)
который вызывает Исключение ConstraintViolation. Исправление состоит в том, чтобы явно определить две таблицы Join, используя
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name="Container_PrimaryElements")
List<Element> primaryElements;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name="Container_SecondaryElements")
List<Element> secondaryElements;
который, похоже, работает.
Однако, я все еще интересно, есть ли
- являются лучшие решения для этой проблемы?
- с использованием таблицы соединений для отношений ManyToMany «должен» фактически работать (согласно спецификации)?
Спасибо, я отредактирую пост как можно скорее. –
Однако, если я правильно вас понял, обе проблемы, о которых вы упомянули, должны также существовать, когда есть только список «первичных элементов»? Однако это прекрасно работает ... или я пропустил те моменты, о которых вы говорили? –
Когда вы не учитываете 'secondaryElements', больше нет прямого отношения от контейнера1 к элементу2 (но все же непрямо от контейнера1 до элемента1 до контейнера2 к элементу2), вероятно, вызывая JPA INSERT в другом порядке, в результате чего генерируется идентификатор работают по-другому. Вот почему я попросил журналы SQL;) – duckstep