[jboss-user] [Persistence, JBoss/CMP, Hibernate, Database] - "Cached Item Was Locked" causing Select Statement: EHCache +

cloutierm do-not-reply at jboss.com
Sun Mar 15 16:28:36 EDT 2009


I am having trouble with getting some caching to work with hibernate exactly the way I would like.  I created some example code to replicate this problem I am having. 

I have one object that contains instances of itself.  For instance, a Part that is made up of more Parts.  

I really need to minimize the select statements that Hibernate is using when an updated object comes in.  After going through the logs, I see this log output that is causing a SELECT statement:

Cached item was locked: com.cache.dataobject.Part.parts#1

What can I change in my annotation mappings, xml files, or logic to keep the cached item from being locked?  I would really like to get rid of that select statement.

I included the Entity, DataObject, code I am testing with, and log output.  


Hibernate version: 3.4

EHCache Version: 1.2.3 (Included with Hibernate Download)

Part DataObject

package com.cache.dataobject;
  | 
  | import java.io.Serializable;
  | import java.lang.String;
  | import java.util.List;
  | 
  | import javax.persistence.*;
  | 
  | import org.hibernate.annotations.Cache;
  | import org.hibernate.annotations.CacheConcurrencyStrategy;
  | 
  | import static javax.persistence.CascadeType.ALL;
  | 
  | /**
  |  * Entity implementation class for Entity: Part
  |  * 
  |  */
  | @Entity
  | @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
  | public class Part implements Serializable {
  | 
  | 	private int id;
  | 	private String name;
  | 	private static final long serialVersionUID = 1L;
  | 	private Part mainPart;
  | 	private List<Part> parts;
  | 
  | 	public Part() {
  | 		super();
  | 	}
  | 
  | 	@Id
  | 	public int getId() {
  | 		return this.id;
  | 	}
  | 
  | 	public void setId(int id) {
  | 		this.id = id;
  | 	}
  | 
  | 	@Column(name = "PART_NAME")
  | 	public String getName() {
  | 		return this.name;
  | 	}
  | 
  | 	public void setName(String name) {
  | 		this.name = name;
  | 	}
  | 
  | 	@ManyToOne(cascade = ALL)
  | 	public Part getMainPart() {
  | 		return mainPart;
  | 	}
  | 
  | 	public void setMainPart(Part mainPart) {
  | 		this.mainPart = mainPart;
  | 	}
  | 
  | 	@OneToMany(cascade = ALL)
  | 	@JoinColumn(name = "mainPart_id", referencedColumnName = "id")
  | 	@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
  | 	public List<Part> getParts() {
  | 		return parts;
  | 	}
  | 
  | 	public void setParts(List<Part> parts) {
  | 		this.parts = parts;
  | 	}
  | 
  | }

CacheDao
package com.cache.dao;
  | 
  | import java.util.List;
  | 
  | import javax.ejb.Stateless;
  | import javax.persistence.EntityManager;
  | import javax.persistence.PersistenceContext;
  | import javax.persistence.Query;
  | 
  | import com.cache.dataobject.Part;
  | 
  | /**
  |  * Session Bean implementation class CacheDao
  |  */
  | @Stateless(mappedName = "ejb/CacheDao")
  | public class CacheDao implements CacheDaoRemote {
  | 	
  | 	@PersistenceContext(unitName="CacheProjectUnit")
  | 	EntityManager em;
  | 
  |     /**
  |      * Default constructor. 
  |      */
  |     public CacheDao() {
  |         // TODO Auto-generated constructor stub
  |     }
  |     
  |     public Part addPart(Part part){
  |     	System.out.println("CALLED PERSIST");
  |     	em.persist(part);
  |     	return part;
  |     }
  |     
  |     public Part updatePart(Part part){
  |     	System.out.println("CALLED MERGE");
  |     	em.merge(part);
  |     	return part;
  |     }
  | 
  | }

Test Client Code

  | package com.cache.dao;
  | 
  | import java.util.ArrayList;
  | import java.util.List;
  | 
  | import javax.naming.InitialContext;
  | import javax.naming.NamingException;
  | 
  | import com.cache.dao.CacheDaoRemote;
  | import com.cache.dataobject.Part;
  | 
  | 
  | public class test {
  | 
  | 	/**
  | 	 * @param args
  | 	 */
  | 	public static void main(String[] args) {
  | 		InitialContext ctx;
  | 		try {
  | 			ctx = new InitialContext();
  | 			CacheDaoRemote dao = (CacheDaoRemote) ctx.lookup("ejb/CacheDao");
  | 			Part computer = new Part();
  | 			computer.setId(1);
  | 			computer.setName("Computer");
  | 			
  | 			List<Part> parts = new ArrayList<Part>();
  | 			
  | 			Part cpu = new Part();
  | 			cpu.setId(2);
  | 			cpu.setName("CPU");
  | 			
  | 			Part monitor = new Part();
  | 			monitor.setId(3);
  | 			monitor.setName("Monitor");
  | 			
  | 			parts.add(cpu);
  | 			parts.add(monitor);
  | 			
  | 			computer.setParts(parts);
  | 			
  | 			dao.addPart(computer);
  | 			
  | 			computer.setName("DellComputer");
  | 			
  | 			dao.updatePart(computer);
  | 			
  | 			
  | 		} catch (NamingException e) {
  | 			// TODO Auto-generated catch block
  | 			e.printStackTrace();
  | 		}
  | 
  | 	}
  | 
  | }
  | 

Persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
  | <persistence version="1.0"
  | 	xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  | 	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
  | 	<persistence-unit name="CacheProjectUnit">
  | 		<provider>org.hibernate.ejb.HibernatePersistence</provider>
  | 		<!-- JNDI name of the database resource to use -->
  | 		<jta-data-source>jdbc/H2Pool</jta-data-source>
  | 		<properties>
  | 			<!-- The database dialect to use -->
  | 			<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
  | 			<!-- drop and create tables at deployment -->
  | 			<property name="hibernate.hbm2ddl.auto" value="create-drop" />
  | 			<property name="hibernate.max_fetch_depth" value="3" />
  | 			<!-- Hibernate Query Language (HQL) parser. -->
  | 			<property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider" />
  | 		</properties>
  | 	</persistence-unit>
  | </persistence>

EhCache.xml

<ehcache>
  |     <diskStore path="java.io.tmpdir"/>
  | 
  |     <defaultCache
  |             maxElementsInMemory="10000"
  |             eternal="false"
  |             timeToIdleSeconds="120"
  |             timeToLiveSeconds="120"
  |             overflowToDisk="true"
  |             diskPersistent="false"
  |             diskExpiryThreadIntervalSeconds="120"
  |             memoryStoreEvictionPolicy="LRU"
  |             />
  |             
  |     
  |     <cache name = "com.cache.dataobject.Part"
  | 		maxElementsInMemory="100000"
  | 		eternal="true"
  | 		diskPersistent="false"
  | 		timeToIdleSeconds="0"
  | 		timeToLiveSeconds="0"
  | 	/>
  | 	
  | 	
  | 	<cache name = "com.cache.dataobject.Part.parts"
  | 		maxElementsInMemory="100000"
  | 		eternal="true"
  | 		diskPersistent="false"
  | 		timeToIdleSeconds="0"
  | 		timeToLiveSeconds="0"
  | 	/>
  | 	
  | 	
  | </ehcache>


Output Log: 

INFO: CALLED PERSIST
FINEST: Cache lookup: com.cache.dataobject.Part#1
FINE: key: com.cache.dataobject.Part#1
FINE: Element for com.cache.dataobject.Part#1 is null
FINEST: Cache miss: com.cache.dataobject.Part#1
FINEST: Cache lookup: com.cache.dataobject.Part#2
FINE: key: com.cache.dataobject.Part#2
FINE: Element for com.cache.dataobject.Part#2 is null
FINEST: Cache miss: com.cache.dataobject.Part#2
FINEST: Cache lookup: com.cache.dataobject.Part#3
FINE: key: com.cache.dataobject.Part#3
FINE: Element for com.cache.dataobject.Part#3 is null
FINEST: Cache miss: com.cache.dataobject.Part#3
FINEST: Invalidating: com.cache.dataobject.Part.parts#1
FINE: key: com.cache.dataobject.Part.parts#1
FINE: Element for com.cache.dataobject.Part.parts#1 is null
FINE: insert into Part (mainPart_id, PART_NAME, id) values (?, ?, ?)
FINE: insert into Part (mainPart_id, PART_NAME, id) values (?, ?, ?)
FINE: insert into Part (mainPart_id, PART_NAME, id) values (?, ?, ?)
FINE: update Part set mainPart_id=? where id=?
FINE: update Part set mainPart_id=? where id=?
FINEST: Inserting: com.cache.dataobject.Part#1
FINE: key: com.cache.dataobject.Part#1
FINE: Element for com.cache.dataobject.Part#1 is null
FINEST: Inserted: com.cache.dataobject.Part#1
FINEST: Inserting: com.cache.dataobject.Part#2
FINE: key: com.cache.dataobject.Part#2
FINE: Element for com.cache.dataobject.Part#2 is null
FINEST: Inserted: com.cache.dataobject.Part#2
FINEST: Inserting: com.cache.dataobject.Part#3
FINE: key: com.cache.dataobject.Part#3
FINE: Element for com.cache.dataobject.Part#3 is null
FINEST: Inserted: com.cache.dataobject.Part#3
FINEST: Releasing: com.cache.dataobject.Part.parts#1
FINE: key: com.cache.dataobject.Part.parts#1

INFO: CALLED MERGE
FINEST: Cache lookup: com.cache.dataobject.Part#1
FINE: key: com.cache.dataobject.Part#1
FINEST: Cache hit: com.cache.dataobject.Part#1
FINEST: Cache lookup: com.cache.dataobject.Part#1
FINE: key: com.cache.dataobject.Part#1
FINEST: Cache hit: com.cache.dataobject.Part#1
FINEST: Cache lookup: com.cache.dataobject.Part#2
FINE: key: com.cache.dataobject.Part#2
FINEST: Cache hit: com.cache.dataobject.Part#2
FINEST: Cache lookup: com.cache.dataobject.Part#2
FINE: key: com.cache.dataobject.Part#2
FINEST: Cache hit: com.cache.dataobject.Part#2
FINEST: Cache lookup: com.cache.dataobject.Part#3
FINE: key: com.cache.dataobject.Part#3
FINEST: Cache hit: com.cache.dataobject.Part#3
FINEST: Cache lookup: com.cache.dataobject.Part#3
FINE: key: com.cache.dataobject.Part#3
FINEST: Cache hit: com.cache.dataobject.Part#3
FINEST: Cache lookup: com.cache.dataobject.Part.parts#1
FINE: key: com.cache.dataobject.Part.parts#1
FINEST: Cached item was locked: com.cache.dataobject.Part.parts#1
FINE: select parts0_.mainPart_id as mainPart3_1_, parts0_.id as id1_, parts0_.id as id18_0_, parts0_.mainPart_id as mainPart3_18_0_, parts0_.PART_NAME as PART2_18_0_ from Part parts0_ where parts0_.mainPart_id=?
FINEST: Caching: com.cache.dataobject.Part.parts#1
FINE: key: com.cache.dataobject.Part.parts#1
FINEST: Cached: com.cache.dataobject.Part.parts#1
FINEST: Invalidating: com.cache.dataobject.Part.parts#2
FINE: key: com.cache.dataobject.Part.parts#2
FINE: Element for com.cache.dataobject.Part.parts#2 is null
FINEST: Invalidating: com.cache.dataobject.Part.parts#3
FINE: key: com.cache.dataobject.Part.parts#3
FINE: Element for com.cache.dataobject.Part.parts#3 is null
FINEST: Invalidating: com.cache.dataobject.Part.parts#1
FINE: key: com.cache.dataobject.Part.parts#1
FINEST: Invalidating: com.cache.dataobject.Part#1
FINE: key: com.cache.dataobject.Part#1
FINE: update Part set mainPart_id=?, PART_NAME=? where id=?
FINE: update Part set mainPart_id=null where mainPart_id=?
FINE: update Part set mainPart_id=null where mainPart_id=?
FINEST: Updating: com.cache.dataobject.Part#1
FINE: key: com.cache.dataobject.Part#1
FINEST: Updated: com.cache.dataobject.Part#1
FINEST: Releasing: com.cache.dataobject.Part.parts#2
FINE: key: com.cache.dataobject.Part.parts#2
FINEST: Releasing: com.cache.dataobject.Part.parts#3
FINE: key: com.cache.dataobject.Part.parts#3
FINEST: Releasing: com.cache.dataobject.Part.parts#1
FINE: key: com.cache.dataobject.Part.parts#1

View the original post : http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4218103#4218103

Reply to the post : http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&p=4218103



More information about the jboss-user mailing list