2012-01-05 1 views
2

У меня есть одна взаимосвязь «многие-ко-многим» в моей модели. Есть два объекта: Чрезвычайные ситуации и Экипажи (экипажи могут посещать множество чрезвычайных ситуаций, и наоборот). части кода, отвечающие за внешний вид отношений следующим образом:JPA, Eclipselink, Many-to-many: зависимая коллекция не обновляется

@JoinTable(name = "CREWS_ON_EMERGENCIES", joinColumns = { 
    @JoinColumn(name = "EMERGENCY_ID", referencedColumnName = "EMERGENCY_ID", nullable = false)}, inverseJoinColumns = { 
    @JoinColumn(name = "CREW_ID", referencedColumnName = "CREW_ID", nullable = false)}) 
@ManyToMany(fetch= FetchType.EAGER) 
private Collection<Crew> crewList; 

и

@ManyToMany(mappedBy="crewList", fetch= FetchType.EAGER) 
private Collection<Emergency> emergencyList; 

Экипаж является зависимым - emergencyList обновляется при добавлении новой Emergency со списком команд приняли участие.

На самом деле база данных обновляется отлично, и новые записи появляются в таблице CREWS_ON_EMERGENCIES сразу после закрытия транзакции. Но если добавить новую аварийную ситуацию, а затем отобразить список всех экипажей и чрезвычайных ситуаций, которые они посетили, последняя аварийная ситуация не будет отображаться (очевидно, «EmergencyList» устарел). Он появится только при перезапуске сервера (Tomcat) или в режиме отладки.

Emergency сохранить код():

@Transactional 
public void save(Emergency e) { 
    entityManager.persist(e); 
    entityManager.flush(); 
} 

Выбранные команды автоматически добавляются в коллекцию crewList от Spring MVC.

Кто-нибудь знает, почему это происходит так, как это и каково решение?

ответ

1

Я вижу две потенциальные проблемы здесь:

  • ваш код не поддерживают обе стороны двунаправленного ассоциации. Если экипаж добавлен к чрезвычайной ситуации, чрезвычайная ситуация также должна быть добавлена ​​к экипажу (и наоборот). JPA не поддерживает согласованность графа объектов для вас.
  • Если вам нужно перезапустить Tomcat, чтобы увидеть изменения, это означает, что диспетчер объектов никогда не закрывается и не открывается повторно, а его кеш-объекты все еще содержат объекты, которые были загружены в предыдущую транзакцию. Должно быть что-то не так с тем, как вы используете диспетчер объектов. Используете ли вы транзакционную поддержку JPA, предлагаемую Spring.

Замечание: когда я вижу, что EAGER используется по обе стороны от ассоциации «многие-ко-многим», я сразу же думаю: «это приложение будет медленным». Нагрузка в чрезвычайной ситуации будет загружать все ее экипажи, которые будут загружать все их чрезвычайные ситуации, которые будут загружать все их экипажи ... рекурсивно. Вы можете загрузить половину базы данных.

+0

Благодарим вас за быстрый ответ! Я добавил следующие строки в мой контроллер для поддержки экипажей, и это сработало! 'for (Crew c: emergency.getCrewList()) { c.getEmergencyList(). add (аварийный); crewDao.merge (c); } ' –

+0

Учитывая выбор EAGER - да, возможно, приложение немного медленное, но у меня были странные ошибки, поэтому он не работал. Может быть, я что-то испортил, но, честно говоря, у меня нет времени идти глубже. –

+0

О, извините за мое невнимание. Добавление фрагмента кода, описанного выше, создает новую проблему. Каждая новая аварийная ситуация создается дважды. Пока нет решения. –

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