When enabling ehCache (2.7.0) as Hibernate (4.3.7) Second level cache, Hibernate returns the old collection association.
Model: A Member has a Wallet with Wallet transactions.
Scenario: a Wallet transaction is added to a Member in a transaction (with ehcache enabled). However, after the scenario (after the commit), the Wallet transaction isn't present in the Member, whereas it's present in the db.
Scenarios testing Code:
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();
The hibernate model member snippet:
<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
The MemberDefault and WalletDefault class snippets:
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;
}
}
Notes:
I debugged, enabled hibernate/ehcache debug logging, modified the cache settings in hibernate, tried older Hibernate 4 and ehCache version, but don't seem to solve it, a bit frustrating.
Please some advice on how to solve this?
I solved it by always assigning an instance to the wallet field (hibernate component) in MemberDefault. That is, instead of:
private Wallet wallet;
we had to use:
private Wallet wallet = new WalletDefault();
in the MemberDefault class.
Is this a bug, or does it has any logic ? I think it is a bug as Hibernate knows that it's a component of type WalletDefault from the hibernate config. (I discovered it by removing the Wallet component for testing)
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments