2015-02-25 2 views
0

Я не знал, было ли уместно удалить исходный вопрос, но добавил более краткое объяснение внизу, надеюсь, устраняя необходимость просмотра всех деталей.JPA (EclipseLink), возвращающий нуль в списке

Я получаю непоследовательные результаты и не могу понять, что я делаю неправильно. Он относится к веб-приложению EE7 с управляемым контейнером Entity Manager, Java 8, EclipseLink 2.5.2, netbeans 8.0.2 IDE.

Существует родитель потомок отображается в виде двунаправленной связи:

Таблица событий является родителем, который сопоставляется Игры

@OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "event") 
@OrderBy("gameType, round") 
private List<Game> gameList; 

Игры карты Событие, как

@JoinColumn(name = "EVENT", referencedColumnName = "ID") 
@ManyToOne(fetch = FetchType.EAGER, optional = false) 
private Event event; 

Шаг 1: Используя веб-интерфейс, я создаю событие и одну игру. Игра добавляется в список событий и событие в игру. em.persist (event) вызывается, чтобы сохранить все это. -> отлично работает

Шаг 2: Редактировать событие создать новую игру - Добавить событие в игре, em.persist (игры) с em.flush(), чтобы получить идентификатор и добавить его к список игр в событиях После завершения редактирования em.update (event) -> обновление базы данных точно так, как ожидалось -> BTW Я понимаю, что лучше не работать в игре, пока событие не будет готово к сохранению разрешите «выйти». Это то, что я планирую сделать, но пока не имею хорошей справки о лучших методах для этого, и мой опыт работы с каскадом неоднозначен.

Наконец-то проблема: - 100% времени «второй шаг» работает правильно с базой данных, но когда я получаю событие для дальнейших изменений, у события есть дополнительная запись в списке игр со значением null. - если я снова и снова закрываю и перезапускаю приложение, иногда это случается, а иногда и нет. База данных всегда остается в тактике и точно так, как ожидалось. - одновременное использование другого браузера с той же машины или другого имеет тот же результат - очевидно, что кеш постоянной памяти может находиться в противоречивом состоянии, но я не смог определить, что-то не так или ошибка EclipseLink

Ранее я сообщил о problem, который оказался ошибкой EclipseLink, связанной с классом IndirectList и Java 8, поэтому я не уверен, что я делаю что-то неправильно или если это похоже.

Заранее благодарен!

После некоторого чтения через JPA JSR мне интересно, правильно ли я понимаю. Использование контейнера с управляемой транзакцией, управляемой транзакциями в контейнере, в EE, по существу означает, что транзакция начинается с вызова метода в EJB и заканчивается возвратом. Поэтому получение информации для размещения чего-либо на экране - это одна транзакция и обновление после изменений пользователей - другое. Или, что более ясно, я почти всегда работаю с отдельными сущностями.

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

Это справедливый подход или он каким-то образом испорчен?


У меня все еще есть эта проблема и, возможно, отследил ее чуть дальше. У меня есть ряд связанных записей с двунаправленными ссылками через внешние ключи @ManyToOne и @OneToMany.

Это по существу простой цепь с обратной ссылкой:

  • Entity А содержит список B и B внешнего ключа A
  • Entity B содержит список C, и C иностранный ключ к B

шаги для воспроизведения:

  1. новый C (B, а также другие параметры конструктора)
  2. B.add (С)
  3. Установите другие свойства в C
  4. em.persist (С) для обеспечения ID
  5. em.update (B), чтобы зарегистрировать обновление Отношения

После каждый шаг, включая 4, все выглядит правильно. Я думал, что, возможно, шаг 2 должен следовать 4, но я не уверен, что это изменит ситуацию. После шага 5,

  • В имеет ту же ячейку памяти и указатель на C.
  • С был обновлен с ячейками памяти нового для ссылок на B и A.
  • то есть указатель обратно B и A в C является другой ячейкой памяти, чем источник

Впоследствии, когда я обновляю объект с помощью em.find(), объект B имеет записи NULL в списке C, хотя база данных MySQL отражает то, что я ожидаю.

Я, очевидно, сделал что-то неправильно, что повредило кеш непрерывности EclipseLink. Единственное, что я нашел, чтобы исправить это, - это перезапустить приложение, чтобы удалить кеш.

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

+0

Как получить доступ к списку игр? Ошибка в Eclipselink относится к ошибочной реализации в сочетании с API потока Java8. – PepperBob

+0

Я создал класс, специально для преодоления ошибки и использования его при доступе к чему-либо, связанному с JPA. – GolfAddict

+0

Извините, я нажал Enter выше и приурочен.Я создал класс для каждого объекта специально для преодоления ошибки, основанной на предположении в другой ссылке. Он сверлит и возвращает actuaitem, чтобы я мог свободно использовать Java 8. По сути EclipseLink.game (gameList) .stream ... Он отлично работает, и я использую его везде. – GolfAddict

ответ

0

Проблема была в конечном счете отслежена до ошибки кодирования. В частности, ссылочный указатель, возвращаемый из em.merge(), не обновлялся в связанных объектах, что приводило к множественным копиям и искажениям настойчивости.

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

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