2013-10-14 1 views
1

У меня есть Curriculum объект, который следующим образом:Проблемы с отношением @ManyToMany сохраняющейся в справочные таблицы

@Entity 
public class Curriculum { 

    @ManyToMany 
    private Set<Language> languages; 
    ... 

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

Как я могу убедиться, что, когда вызов упорствовать сделан, линия вставляется в curriculum таблицу, таблица curriculum_languages отображения , но не вlanguage таблицы, как это справочная таблица, которая уже заселена?

редактировать 1:

-Вот ошибка я получаю, если я не указать Cascade.ALL атрибут:

org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.bignibou.domain.Language 

-Если я заданным Cascade.ALL, новые линии с новыми идентификаторами попадают в таблицу language, которая, очевидно, не то, что я хочу ...

Редактировать 2: Обратите внимание, что я использую Spr ING JPA данных для того, чтобы сохраниться мои экземпляры и данные, поступающие из браузера является объект JSON следующим образом:

{"curriculum":{"languages":[{"id":46,"description":"Français"},{"id":30,"description":"Chinois"}],"firstName":"Julianito","dateOfBirth":"1975-01-06","telephoneNumber":"0608965874","workExperienceInYears":3,"maxNumberChildren":1,"drivingLicense":true}} 

ответ

0

Я забыл упомянуть, что использую оптимистичную блокировку. В том числе поля версии в JSon сортирует вопрос:

"languages":[{"id":46,"description":"Français","version":0}],... 

Было бы замечательно, если бы кто-то любезно предоставить объяснение этому, хотя ...

редактировать: поле версии:

@Version 
@Column(name = "version") 
private Integer Curriculum.version; 
+0

Очень интересно. Это как-то еще вопрос, потому что я действительно задавался вопросом, почему вы получаете это исключение, и я не знаю :) –

+0

Можете ли вы показать, как выглядит ваше поле @Version? Какой тип ('int' или' Integer')? –

+0

Насколько я знаю, поле @Version может не быть нулевым (если объект уже сохранен, см. Этот http://stackoverflow.com/questions/16183013/null-version-fields-in-jpa). А теперь просто презумпция: поскольку при декодировании строки JSON без этого поля значение null, hibernate считает единственный случай, когда он может быть нулевым, - это когда он находится в управляемом состоянии (но я не могу понять, почему). –

0

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

Логика этого заключается в следующем:

  • Когда объект языка приходит в ваше приложение и десериализации из JSON, то есть поле ID уже возложенную на него.
  • Когда вы пытаетесь сохранить учебный план (с десериализацией языков из JSON), JPA запутывается в отношении этих идентификаторов, что, с одной стороны, «должно» знать об этих объектах (установлены идентификаторы), но, с другой стороны, активная JPA сессия ничего не знает о них (они пришли из внешнего мира JSON)
  • Так что выбор языков по ID говорит JPA, кто есть кто.
+0

Спасибо. Вы имеете в виду использование идентификаторов? Также: почему у меня есть эта проблема с JSon, а не с обычными форматами html? – balteo

+0

Да, просто введите языки по id из базы данных. Я обновлю ответ – WeMakeSoftware

+0

Обновлен ответ – WeMakeSoftware

0

Что произойдет, когда несуществующий Language поставляется с экземпляром Curriculum? Если случай Language просто игнорируется или должен быть выброшен Exception?

Если необходимо исключить исключение, просто оберните код, который сохраняется в объекте в блоке try-catch, и выбросите свое собственное исключение. Если язык следует просто игнорировать, просто удалите его из List<Language> до его сохранения, например, если идентификатор Language равен NULL.

+0

Привет, Андрей, спасибо за ваш ответ. Моя забота о том, чтобы извлечь экземпляры языков из db, чтобы сохранить строки в таблице сопоставления учебных планов. Это выглядит для меня как обходное/hack ... – balteo

+0

Зачем вам нужно извлекать их из базы данных? Hibernate позаботится о том, чтобы вставить строки в таблицу сопоставления «curriculum_languages» без этого. Если пользователь передаст некоторые несуществующие идентификаторы языков, база данных должна выполнить проверки и должна вызывать 'ForeignKeyConstraintException', но все происходит в фоновом режиме. –

+0

Я вижу. Беда в том, что с моей текущей настройкой то, что вы посоветуете, не работает (если только мне не хватает чего-то ...). Посмотрите мой мой ** edit 1 ** – balteo