Hibernate version: 3.2.4.sp1
JBoss version: 4.2.2 GA
Name and version of the database: MySQL 5.0.51a
Ok, first small description of domain objects. We are using 4 classes: Session, User, Member and Guest. Member and Guest extends User class. Definition of classes:
Code:
@Entity
@Table(name = "session")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE, include = "all")
public class Session extends AbstractEntity {
...
@OneToOne (optional = false, mappedBy = "session")
private User user;
...
}
Code:
@Entity
@Table(name = "user", uniqueConstraints = { @UniqueConstraint(columnNames = { "nick" }) })
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "user_type", discriminatorType = DiscriminatorType.STRING, length = 1)
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE, include = "non-lazy")
public abstract class User extends AbstractEntity {
...
@Column(nullable = false)
private String nick;
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST })
private Collection<Rating> ratings;
...
}
Code:
@Entity
@DiscriminatorValue(value = "G")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE, include = "non-lazy")
public class Guest extends User {
...
}
Code:
@Entity
@DiscriminatorValue(value = "M")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE, include = "non-lazy")
public class Member extends User {
...
}
The problem is when I get Session by Id (in AbstractEntity) second level cache is not used for User:
Code:
2008-10-15 14:54:24,178 DEBUG [org.hibernate.impl.SessionImpl] opened session at timestamp: 12240716641
2008-10-15 14:54:24,178 DEBUG [org.hibernate.ejb.AbstractEntityManagerImpl] Looking for a JTA transaction to join
2008-10-15 14:54:24,178 DEBUG [org.hibernate.jdbc.JDBCContext] successfully registered Synchronization
2008-10-15 14:54:24,178 DEBUG [org.hibernate.ejb.AbstractEntityManagerImpl] Looking for a JTA transaction to join
2008-10-15 14:54:24,178 DEBUG [org.hibernate.ejb.AbstractEntityManagerImpl] Transaction already joined
2008-10-15 14:54:24,178 DEBUG [org.hibernate.cache.NonstrictReadWriteCache] Cache lookup: xxx.persistence.session.Session#1
2008-10-15 14:54:24,179 DEBUG [com.googlecode.hibernate.memcached.HashCodeKeyStrategy] Transformed key [xxx.persistence.session.Session#1] to hashCode [1]
2008-10-15 14:54:24,179 DEBUG [com.googlecode.hibernate.memcached.HashCodeKeyStrategy] Final cache key: [Konfero_ear,BusinessModule_jar,konfero.xxx.persistence.session.Session:0:1]
2008-10-15 14:54:24,179 DEBUG [com.googlecode.hibernate.memcached.MemcachedCache] Memcache.get(Konfero_ear,BusinessModule_jar,konfero.xxx.persistence.session.Session:0:1)
2008-10-15 14:54:24,179 DEBUG [com.googlecode.hibernate.memcached.spymemcached.SpyMemcache] MemcachedClient.get(Konfero_ear,BusinessModule_jar,konfero.xxx.persistence.session.Session:0:1)
2008-10-15 14:54:24,179 DEBUG [org.hibernate.cache.NonstrictReadWriteCache] Cache hit
2008-10-15 14:54:24,180 DEBUG [org.hibernate.loader.Loader] loading entity: [xxx.persistence.user.User#1]
2008-10-15 14:54:24,180 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
2008-10-15 14:54:24,180 DEBUG [org.hibernate.jdbc.ConnectionManager] opening JDBC connection
2008-10-15 14:54:24,180 DEBUG [org.hibernate.SQL] select user0_.id as id9_0_, user0_.nick as nick9_0_, user0_.avatar_id as avatar11_9_0_, user0_.session_id as session9_9_0_, user0_.email as email9_0_, user0_.password as password9_0_, user0_.active as active9_0_, user0_.email_verification_id as email10_9_0_, user0_.ratingCount as ratingCo7_9_0_, user0_.rating as rating9_0_, user0_.user_type as user1_9_0_ from user user0_ where user0_.session_id=?
2008-10-15 14:54:24,180 INFO [STDOUT] Hibernate: select user0_.id as id9_0_, user0_.nick as nick9_0_, user0_.avatar_id as avatar11_9_0_, user0_.session_id as session9_9_0_, user0_.email as email9_0_, user0_.password as password9_0_, user0_.active as active9_0_, user0_.email_verification_id as email10_9_0_, user0_.ratingCount as ratingCo7_9_0_, user0_.rating as rating9_0_, user0_.user_type as user1_9_0_ from user user0_ where user0_.session_id=?
2008-10-15 14:54:24,181 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to open ResultSet (open ResultSets: 0, globally: 0)
2008-10-15 14:54:24,181 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to close ResultSet (open ResultSets: 1, globally: 1)
2008-10-15 14:54:24,181 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
2008-10-15 14:54:24,181 DEBUG [org.hibernate.jdbc.ConnectionManager] aggressively releasing JDBC connection
2008-10-15 14:54:24,181 DEBUG [org.hibernate.jdbc.ConnectionManager] releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
2008-10-15 14:54:24,181 DEBUG [org.hibernate.engine.StatefulPersistenceContext] initializing non-lazy collections
2008-10-15 14:54:24,181 DEBUG [org.hibernate.loader.Loader] done entity load
2008-10-15 14:54:24,181 DEBUG [org.hibernate.engine.StatefulPersistenceContext] initializing non-lazy collections
2008-10-15 14:54:24,181 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] processing flush-time cascades
2008-10-15 14:54:24,181 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] dirty checking collections
2008-10-15 14:54:24,181 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] Flushed: 0 insertions, 0 updates, 0 deletions to 1 objects
2008-10-15 14:54:24,181 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] Flushed: 0 (re)creations, 0 updates, 0 removals to 0 collections
2008-10-15 14:54:24,181 DEBUG [org.hibernate.pretty.Printer] listing entities:
2008-10-15 14:54:24,181 DEBUG [org.hibernate.pretty.Printer] xxx.persistence.session.Session{id=1, sessionId=component[webSessionId]{webSessionId=TestSession0.9709044681433046}, user=null}
2008-10-15 14:54:24,181 DEBUG [org.hibernate.jdbc.ConnectionManager] aggressively releasing JDBC connection
2008-10-15 14:54:24,181 DEBUG [org.jboss.ejb3.entity.ManagedEntityManagerFactory] ************** closing entity managersession **************
i.e. Session#1 is found in cache but we immediatelly try to fetch User (due to one-to-one relation, I think) and Hibernate doesn't even try to hit the cache, it searches User in database.
I've tried this with EhCache and Memcached, but I think the problem lies in Hibernate.
Question: how I should configure second-level cache/hierarchy of objects to use cache instead of db-lookup each time Session is being fetched?