2014-12-26 4 views
1

При включении ehCache (2.7.0) в качестве спящего режима (4.3.7) кеш второго уровня Hibernate возвращает старую ассоциацию коллекции.грязные чтения ассоциаций в кэше второго уровня спящего режима

Модель: У члена есть кошелек с кошельковыми транзакциями.

Сценарий: Операция кошелька добавляется к члену в транзакции (с включенным ehcache). Однако после сценария (после фиксации) транзакция Кошелька отсутствует в члене, тогда как она присутствует в db.

Сценарии тестирования Код:

startTransaction(); // used to create a transaction through Spring. 
member = findMemberById(); // Hibernate "get()" to retrieve member from Db. 
final WalletTransaction walTx = member.getEnsureWallet().addWalletTransaction(10); // add wallet tx of 10 euro. 
member.saveOrUpdate(); // will update the member and the wallet transactions through cascading 
commitTransaction(); 

// assert wallet transaction is present 
startTransaction(); 
final Taxer mem = findMemberById(member.getId()); // refresh member in session through it's PK, logging indicates it comes from cache. 
// final Taxer mem = findMemberByLoginName(member.getLoginName()); // when retrieving the member through it's loginName, the test works. 
assertTrue(mem.containsWalletTransaction(walTx)); // FAILS 
commitTransaction(); 

элемент модели гибернации сниппет:

<class name="com.core.domain.MemberDefault" table="mem" discriminator-value="Mem" > 
    <component name="wallet" class="com.core.domain.Wallet"> 
     <set name="transactions" table="wallet_tx" cascade="save-update, delete" > 
      <!--cache usage="read-write" /--> 
      <key column="idMember" not-null="true" /> 

      <composite-element class="com.core.domain.WalletTransactionDefault"> 
       <property name="amount" type="big_decimal" column="amount" /> 
       .... (more props) 
      </composite-element> 
     </set> 
    </component> 
</class 

В MemberDefault и WalletDefault фрагменты класса:

public class MemberDefault implements Member { 
    private Wallet wallet; 
.... 
} 

public class WalletDefault implements Wallet { 
private Set<WalletTransaction> transactions; 

public void setTransactions(Set<WalletTransaction> transactions) { 
    this.transactions = transaction; 
} 

public Set<WalletTransaction> getTransactions() { 
    return this.transactions; 
} 
} 

Примечание:

  1. В случае, если я не добавить сделку бумажника в сделке (удалить первый старт/фиксацию), испытание проводятся с успехом (Выше изолированный код тестирования, чтобы воспроизвести ошибку).
  2. В случае, если я отключу второй уровень, тест работает.
  3. В случае, если я не извлечу элемент из Db через его PK, но через его loginName, так что запрос используется Hibernate, и как таковой кеш запросов, тест работает.

Я отлажен, включено протоколирование спящего режима/EHCache отладки, изменения настроек кэша в спящем режиме, попробовала старые гибернации 4 и Ehcache версию, но, кажется, не решить, немного расстраивает.

Просьба сообщить вам, как это решить?

ответ

0

Я решил это, всегда назначая экземпляр поля кошелька (спящий компонент) в MemberDefault. То есть, вместо того, чтобы:

private Wallet wallet; 

мы должны были использовать:

private Wallet wallet = new WalletDefault(); 

в классе MemberDefault.

Это ошибка, или у нее есть какая-либо логика? Я думаю, что это ошибка, так как Hibernate знает, что это компонент типа WalletDefault из конфигурации hibernate. (я обнаружил это, удалив компонент Кошелька для тестирования)

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