OPENJPA-1856: Make DataCache eviction due to bulk updates configurable.

git-svn-id: https://svn.apache.org/repos/asf/openjpa/branches/2.1.x@1057319 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Richard G. Curtis 2011-01-10 19:11:32 +00:00
parent 92aba0ead7
commit f12970baf2
9 changed files with 99 additions and 8 deletions

View File

@ -80,7 +80,8 @@ public abstract class AbstractDataCache extends AbstractConcurrentEventManager
private String _schedule = null;
protected Set<String> _includedTypes = new HashSet<String>();
protected Set<String> _excludedTypes = new HashSet<String>();
protected boolean _evictOnBulkUpdate = true;
public String getName() {
return _name;
}
@ -541,4 +542,12 @@ public abstract class AbstractDataCache extends AbstractConcurrentEventManager
public DataCache selectCache(OpenJPAStateManager sm) {
return this;
}
public boolean getEvictOnBulkUpdate(){
return _evictOnBulkUpdate;
}
public void setEvictOnBulkUpdate(boolean b){
_evictOnBulkUpdate = b;
}
}

View File

@ -304,4 +304,9 @@ public interface DataCache
* Returns number of read/write request and cache hit ratio data.
*/
public CacheStatistics getStatistics();
/**
* Returns whether the the cache needs to be updated when bulk updates as executed. Defaults to true.
*/
public boolean getEvictOnBulkUpdate();
}

View File

@ -117,7 +117,7 @@ public class DataCacheStoreManager
DataCache cache;
for (Class<?> cls : classes) {
cache = mdr.getMetaData(cls, loader, false).getDataCache();
if (cache != null)
if (cache != null && cache.getEvictOnBulkUpdate())
cache.removeAll(cls, false);
}
}

View File

@ -381,4 +381,14 @@ public class DelegatingDataCache
throw translate(re);
}
}
public boolean getEvictOnBulkUpdate() {
if (_cache == null)
return false;
try {
return _cache.getEvictOnBulkUpdate();
} catch (RuntimeException re) {
throw translate(re);
}
}
}

View File

@ -380,7 +380,7 @@ public class QueryCacheStoreQuery
// evict from the data cache
for (int i = 0; i < cmd.length; i++) {
if (cmd[i].getDataCache() != null)
if (cmd[i].getDataCache() != null && cmd[i].getDataCache().getEvictOnBulkUpdate())
cmd[i].getDataCache().removeAll(
cmd[i].getDescribedType(), true);
}

View File

@ -131,7 +131,7 @@ public abstract class AbstractStoreQuery
} finally {
for (ClassMetaData cmd : getAccessPathMetaDatas(q)) {
DataCache cache = cmd.getDataCache();
if (cache != null) {
if (cache != null && cache.getEvictOnBulkUpdate()) {
cache.removeAll(cmd.getDescribedType(), true);
}
}
@ -144,7 +144,7 @@ public abstract class AbstractStoreQuery
} finally {
for (ClassMetaData cmd : getAccessPathMetaDatas(q)) {
DataCache cache = cmd.getDataCache();
if (cache != null) {
if (cache != null && cache.getEvictOnBulkUpdate()) {
cache.removeAll(cmd.getDescribedType(), true);
}
}

View File

@ -793,7 +793,7 @@ public class ExpressionStoreQuery
} finally {
for (ClassMetaData cmd : getAccessPathMetaDatas(q)) {
DataCache cache = cmd.getDataCache();
if (cache != null) {
if (cache != null && cache.getEvictOnBulkUpdate()) {
cache.removeAll(cmd.getDescribedType(), true);
}
}
@ -810,7 +810,7 @@ public class ExpressionStoreQuery
} finally {
for (ClassMetaData cmd : getAccessPathMetaDatas(q)) {
DataCache cache = cmd.getDataCache();
if (cache != null) {
if (cache != null && cache.getEvictOnBulkUpdate()) {
cache.removeAll(cmd.getDescribedType(), true);
}
}

View File

@ -21,10 +21,14 @@ package org.apache.openjpa.persistence.datacache;
import javax.persistence.Cache;
import javax.persistence.EntityManager;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
import org.apache.openjpa.persistence.test.SingleEMFTestCase;
public class TestBulkUpdatesDataCacheEviction extends SingleEMFTestCase {
Object[] props = new Object[] { CLEAR_TABLES, CachedEntityStatistics.class, "openjpa.DataCache", "true" };
Object[] noEvictProps = new Object[] { CLEAR_TABLES, CachedEntityStatistics.class
, "openjpa.DataCache", "true(EvictOnBulkUpdate=false)" };
public void setUp() throws Exception {
super.setUp(props);
@ -85,7 +89,58 @@ public class TestBulkUpdatesDataCacheEviction extends SingleEMFTestCase {
em.close();
}
}
public void testUpdateNoEvict(){
OpenJPAEntityManagerFactorySPI emf = createNamedEMF(getPersistenceUnitName(), noEvictProps);
Cache cache = emf.getCache();
OpenJPAEntityManagerSPI em = emf.createEntityManager();
try {
CachedEntityStatistics e = createEntity(em);
assertTrue(cache.contains(CachedEntityStatistics.class, e.getId()));
em.clear();
String update = "UPDATE CachedEntityStatistics s SET s.firstName = :name WHERE s.id = :id";
String name = "name_" + System.currentTimeMillis();
// execute update, this should result in a cache eviction
em.getTransaction().begin();
assertEquals(1, em.createQuery(update).setParameter("name", name).setParameter("id", e.getId())
.executeUpdate());
em.getTransaction().commit();
assertTrue(cache.contains(CachedEntityStatistics.class, e.getId()));
CachedEntityStatistics postUpdate = em.find(CachedEntityStatistics.class, e.getId());
assertNotEquals(name, postUpdate.getFirstName());
}finally{
emf.close();
}
}
public void testDeleteNoEvict() throws Exception {
OpenJPAEntityManagerFactorySPI emf = createNamedEMF(getPersistenceUnitName(), noEvictProps);
Cache cache = emf.getCache();
OpenJPAEntityManagerSPI em = emf.createEntityManager();
try {
CachedEntityStatistics e = createEntity(em);
assertTrue(cache.contains(CachedEntityStatistics.class, e.getId()));
em.clear();
String delete = "DELETE FROM CachedEntityStatistics s WHERE s.id = :id";
// execute update, this should NOT result in a cache eviction
em.getTransaction().begin();
assertEquals(1, em.createQuery(delete).setParameter("id", e.getId()).executeUpdate());
em.getTransaction().commit();
assertTrue(cache.contains(CachedEntityStatistics.class, e.getId()));
em.clear();
CachedEntityStatistics postUpdate = em.find(CachedEntityStatistics.class, e.getId());
assertNotNull(postUpdate);
} finally {
em.close();
}
}
private CachedEntityStatistics createEntity(EntityManager em) {
em.getTransaction().begin();
CachedEntityStatistics e = new CachedEntityStatistics();

View File

@ -345,6 +345,18 @@ to evict values from the cache every 120 minutes.
true(EvictionSchedule='+120')
</programlisting>
</para>
<example id="bulk_update_evict_cache">
<title>
Bulk updates and cache eviction
</title>
<para>
For the example, setting EvictOnBulkUpdate to false will tell OpenJPA to not evict from the DataCache when executing
and UPDATE or DELETE statement. The default for the value is true.
</para>
<para>
<programlisting>&lt;property name="openjpa.DataCache" value="true(EvictOnBulkUpdate=false)"/&gt;</programlisting>
</para>
</example>
<section id="ref_guide_cache_distribution">
<title>Distributing instances across cache partitions</title>
<para>
@ -371,7 +383,7 @@ as follows:
&lt;property name="openjpa.DataCache" value="partitioned(PartitionType=concurrent,partitions=
'(name=a,cacheSize=100),(name=b,cacheSize=200)')"/&gt;
</programlisting>
</example>
</example>
</section>
<para>
The distribution policy is configured by a full-qualified class name that implements