2009-06-29 2 views
4

У меня есть таблица и две базы данных, которые имеют одну и ту же таблицу, но одна является символической ссылкой для другой, и только чтение разрешено в этой таблице.Отключить автоматическое обновление Hibernate на флеше только для чтения только для синонимов только для чтения

Я сопоставил таблицу с Java с помощью Hibernate, и я использую Spring, чтобы установить источник данных Entity Manager как одну из двух баз данных на основе некоторых критериев ввода.

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

Как отключить это обновление только для второго источника данных и сохранить его нормальным для первого?

Update: Глядя на трассировку стека, флеш, кажется, начал здесь:

 

      at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321) 
      at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50) 
      at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027) 
      at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:365) 
      at org.hibernate.ejb.AbstractEntityManagerImpl$1.beforeCompletion(AbstractEntityManagerImpl.java:504) 
      ... 55 more 

Является ли это связано с hibernate.transaction.flush_before_completion недвижимости? Могу ли я установить значение false для второго источника данных?

ответ

7

Скорее всего, ваши сущности становятся «грязными» в тот же момент, когда они загружаются из базы данных, а Hibernate считает, что ему необходимо сохранить изменения. Это происходит, если ваши аксессоры (методы получения и установки) равны , не возвращая то же самое значение или ссылку, которые были установлены Hibernate.

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

Если вы не хотите изменять код, измените отображение на доступ к полю.

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

1

Сначала вам нужно определить, является ли это DDL или DML. Если вы этого не знаете, я рекомендую установить hibernate.show_sql = true, чтобы зафиксировать заявление о нарушении.

Если это DDL, то это, скорее всего, будет Hibernate обновление схемы для вас, и вы хотите дополнительно настроить hibernate.hbm2ddl.auto параметр, чтобы быть «обновление» или "none", в зависимости от того, используете ли вы фактический db или символический (только для чтения), уважительно. Вы можете использовать «validate» вместо того, чтобы ни одного, тоже.

Если это DML, то сначала я бы определил, является ли ваш код причиной внесения изменений в экземпляр, который все еще привязан к активному сеансу Hibernate. Если это так, то последующее чтение может привести к сбросу этих изменений без явного сохранения объекта (Grails?). Если это так, рассмотреть вопрос об исключении экземпляра, вызывающего сброс (или вместо этого использовать транспортные объекты).

Возможно, вы используете какие-либо аспекты или события жизненного цикла Hibernate для обеспечения аудита объектов? Это также может привести к доступу только для чтения, что приведет к запуску вставки или обновления.

Возможно, вам необходимо предоставить альтернативные сопоставления для класса-нарушителя, если обновляемость поля вступит в игру, но код делает все точно так, как вам хотелось бы (это маловероятно; 0). Если вы находитесь во всем мире аннотаций, это может быть сложно. Если вы работаете с hbm.xml, то упростить альтернативное сопоставление.

+0

Это не DDL, он выпускает только DML, я использую только аннотации и не hbm.xml. Глядя на StackTrace, обновление, похоже, началась из-за этого: 375400 на org.hibernate.impl.SessionImpl.managedFlush (SessionImpl.java:365) 375401 в org.hibernate.ejb.AbstractEntityManagerImpl $ 1.beforeCompletion (AbstractEntityManagerImpl.java:504) 375402 ... 55 еще Это связано с настройкой hibernate.transaction.flush_before_completion? – Arvind