OPENJPA-1532: Enable shared-cache-mode to turn on datacache without needing openjpa.DataCache configuration. Patch contributed by Helen Xu.

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@1396037 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Richard G. Curtis 2012-10-09 13:47:38 +00:00
parent dab8b620f9
commit 4823f1748e
23 changed files with 610 additions and 85 deletions

View File

@ -523,20 +523,32 @@ public abstract class AbstractDataCache extends AbstractConcurrentEventManager
public void setTypes(Set<String> types) { public void setTypes(Set<String> types) {
_includedTypes = types; _includedTypes = types;
if (log.isWarnEnabled())
log.warn(s_loc.get("recommend_jpa2_caching", new Object[]{"Types",
DataCacheMode.ENABLE_SELECTIVE.toString()}));
} }
public void setTypes(String types) { public void setTypes(String types) {
_includedTypes = _includedTypes =
StringUtils.isEmpty(types) ? null : new HashSet<String>(Arrays.asList(Strings.split(types, ";", 0))); StringUtils.isEmpty(types) ? null : new HashSet<String>(Arrays.asList(Strings.split(types, ";", 0)));
if (log.isWarnEnabled())
log.warn(s_loc.get("recommend_jpa2_caching", new Object[]{"Types",
DataCacheMode.ENABLE_SELECTIVE.toString()}));
} }
public void setExcludedTypes(Set<String> types) { public void setExcludedTypes(Set<String> types) {
_excludedTypes = types; _excludedTypes = types;
if (log.isWarnEnabled())
log.warn(s_loc.get("recommend_jpa2_caching", new Object[]{"ExcludeTypes",
DataCacheMode.DISABLE_SELECTIVE.toString()}));
} }
public void setExcludedTypes(String types) { public void setExcludedTypes(String types) {
_excludedTypes = _excludedTypes =
StringUtils.isEmpty(types) ? null : new HashSet<String>(Arrays.asList(Strings.split(types, ";", 0))); StringUtils.isEmpty(types) ? null : new HashSet<String>(Arrays.asList(Strings.split(types, ";", 0)));
if (log.isWarnEnabled())
log.warn(s_loc.get("recommend_jpa2_caching", new Object[]{"ExcludeTypes",
DataCacheMode.DISABLE_SELECTIVE.toString()}));
} }
public DataCache selectCache(OpenJPAStateManager sm) { public DataCache selectCache(OpenJPAStateManager sm) {

View File

@ -143,7 +143,7 @@ public class DataCacheStoreManager
continue; continue;
mods = getModifications(modMap, cache); mods = getModifications(modMap, cache);
data = newPCData(sm); data = newPCData(sm, cache);
data.store(sm); data.store(sm);
mods.additions.add(new PCDataHolder(data, sm)); mods.additions.add(new PCDataHolder(data, sm));
CacheStatistics stats = cache.getStatistics(); CacheStatistics stats = cache.getStatistics();
@ -178,7 +178,7 @@ public class DataCacheStoreManager
// dirty, but maybe it got dropped from the cache in the // dirty, but maybe it got dropped from the cache in the
// interim // interim
if (data == null) { if (data == null) {
data = newPCData(sm); data = newPCData(sm, cache);
data.store(sm); data.store(sm);
mods.newUpdates.add(new PCDataHolder(data, sm)); mods.newUpdates.add(new PCDataHolder(data, sm));
} else { } else {
@ -420,7 +420,7 @@ public class DataCacheStoreManager
// initial load of the data. // initial load of the data.
boolean isNew = data == null; boolean isNew = data == null;
if (isNew) { if (isNew) {
data = newPCData(sm); data = newPCData(sm, cache);
} }
data.store(sm); data.store(sm);
if (isNew) { if (isNew) {
@ -626,7 +626,7 @@ public class DataCacheStoreManager
isNew = data == null; isNew = data == null;
if (isNew) if (isNew)
data = newPCData(sm); data = newPCData(sm, cache);
if (fields == null) if (fields == null)
data.store(sm); data.store(sm);
else else
@ -784,11 +784,11 @@ public class DataCacheStoreManager
/** /**
* Create a new cacheable instance for the given state manager. * Create a new cacheable instance for the given state manager.
*/ */
private DataCachePCData newPCData(OpenJPAStateManager sm) { private DataCachePCData newPCData(OpenJPAStateManager sm, DataCache cache) {
ClassMetaData meta = sm.getMetaData(); ClassMetaData meta = sm.getMetaData();
if (_gen != null) if (_gen != null)
return (DataCachePCData) _gen.generatePCData(sm.getObjectId(), meta); return (DataCachePCData) _gen.generatePCData(sm.getObjectId(), meta);
return new DataCachePCDataImpl(sm.fetchObjectId(), meta, _mgr.selectCache(sm).getName()); return new DataCachePCDataImpl(sm.fetchObjectId(), meta, cache.getName());
} }
/** /**

View File

@ -114,4 +114,6 @@ partition-cache-default-partition: You have specified name "{0}" for a \
name reserved by OpenJPA for internal use and hence can not be used. name reserved by OpenJPA for internal use and hence can not be used.
invalid-types-excluded-types: Failed to configure openjpa.DataCache Types, ExcludedTypes. \ invalid-types-excluded-types: Failed to configure openjpa.DataCache Types, ExcludedTypes. \
Types "{0}" were found in both lists, but can only appear one of the lists. Types "{0}" were found in both lists, but can only appear one of the lists.
recommend_jpa2_caching: You have specified the openjpa.DataCache property "{0}", but using that \
property is not recommended. Please utilize the JPA 2.0 shared-cache-mode element "{1}" \
in conjunction with the javax.persistence.Cacheable annotation instead.

View File

@ -203,28 +203,30 @@ public abstract class AbstractCacheModeTestCase extends AbstractCacheTestCase {
* *
*/ */
public void testRetrieveModeUse() { public void testRetrieveModeUse() {
assertNoSql(new Action() { if (getCacheEnabled()) {
public void run() { assertNoSql(new Action() {
EntityManager em = getEntityManagerFactory().createEntityManager(); public void run() {
em.setProperty(RETRIEVE_MODE_PROP, CacheRetrieveMode.USE); EntityManager em = getEntityManagerFactory().createEntityManager();
for (Class<?> cls : getExpectedInCache()) { em.setProperty(RETRIEVE_MODE_PROP, CacheRetrieveMode.USE);
assertCached(getEntityManagerFactory().getCache(), cls, 1, true); for (Class<?> cls : getExpectedInCache()) {
assertNotNull(em.find(cls, 1)); assertCached(getEntityManagerFactory().getCache(), cls, 1, true);
assertNotNull(em.find(cls, 1));
}
em.close();
} }
em.close(); });
} assertSqlInc(new Action() {
}); public void run() {
assertSqlInc(new Action() { EntityManager em = getEntityManagerFactory().createEntityManager();
public void run() { em.setProperty(RETRIEVE_MODE_PROP, CacheRetrieveMode.USE);
EntityManager em = getEntityManagerFactory().createEntityManager(); for (Class<?> cls : getExpectedNotInCache()) {
em.setProperty(RETRIEVE_MODE_PROP, CacheRetrieveMode.USE); assertCached(getEntityManagerFactory().getCache(), cls, 1, false);
for (Class<?> cls : getExpectedNotInCache()) { assertNotNull(em.find(cls, 1));
assertCached(getEntityManagerFactory().getCache(), cls, 1, false); }
assertNotNull(em.find(cls, 1)); em.close();
} }
em.close(); }, getExpectedNotInCache().length);
} }
}, getExpectedNotInCache().length);
} }
public void updateAndFind(Class<? extends CacheEntity> classToUpdate, int idToUpdate, public void updateAndFind(Class<? extends CacheEntity> classToUpdate, int idToUpdate,
@ -404,45 +406,50 @@ public abstract class AbstractCacheModeTestCase extends AbstractCacheTestCase {
} }
public void testResultsFromQueryAreInCache() { public void testResultsFromQueryAreInCache() {
// clear cache if (getCacheEnabled()) {
getEntityManagerFactory().getStoreCache().evictAll(); // clear cache
getEntityManagerFactory().getQueryResultCache().evictAll(); getEntityManagerFactory().getStoreCache().evictAll();
getEntityManagerFactory().getQueryResultCache().evictAll();
EntityManager em = getEntityManagerFactory().createEntityManager(); EntityManager em = getEntityManagerFactory().createEntityManager();
String query; String query;
for(Class<?> cls : persistentTypes) { for(Class<?> cls : persistentTypes) {
query = "Select e from " + getAlias(cls) + " e"; query = "Select e from " + getAlias(cls) + " e";
List<?> res = em.createQuery(query).getResultList(); List<?> res = em.createQuery(query).getResultList();
assertNotNull(String.format("Expected to find some results when running query %s",query), res); assertNotNull(String.format("Expected to find some results when running query %s",query), res);
assertTrue(String.format("Expected more than 0 results running query %s",query),res.size() != 0 ) ; assertTrue(String.format("Expected more than 0 results running query %s",query),res.size() != 0 ) ;
} }
for(Class<?> cls : getExpectedInCache()) { for(Class<?> cls : getExpectedInCache()) {
assertCached(getEntityManagerFactory().getCache(), cls, 1, true); assertCached(getEntityManagerFactory().getCache(), cls, 1, true);
} }
for(Class<?> cls : getExpectedNotInCache()) { for(Class<?> cls : getExpectedNotInCache()) {
assertCached(getEntityManagerFactory().getCache(), cls, 1, false); assertCached(getEntityManagerFactory().getCache(), cls, 1, false);
}
em.close();
} }
em.close();
} }
public void testResultsFromFindAreInCache() { public void testResultsFromFindAreInCache() {
// clear cache if (getCacheEnabled()) {
getEntityManagerFactory().getStoreCache().evictAll(); // clear cache
getEntityManagerFactory().getQueryResultCache().evictAll(); getEntityManagerFactory().getStoreCache().evictAll();
getEntityManagerFactory().getQueryResultCache().evictAll();
EntityManager em = getEntityManagerFactory().createEntityManager(); EntityManager em = getEntityManagerFactory().createEntityManager();
for(Class<?> cls : persistentTypes) { for(Class<?> cls : persistentTypes) {
assertNotNull(String.format("Expected to find %s::%d from database or from cache", cls, 1),em.find(cls, 1)); assertNotNull(String.format("Expected to find %s::%d from database or from cache", cls, 1),
} em.find(cls, 1));
for(Class<?> cls : getExpectedInCache()) { }
assertCached(getEntityManagerFactory().getCache(), cls, 1, true); for(Class<?> cls : getExpectedInCache()) {
} assertCached(getEntityManagerFactory().getCache(), cls, 1, true);
}
for(Class<?> cls : getExpectedNotInCache()) { for(Class<?> cls : getExpectedNotInCache()) {
assertCached(getEntityManagerFactory().getCache(), cls, 1, false); assertCached(getEntityManagerFactory().getCache(), cls, 1, false);
}
em.close();
} }
em.close();
} }
private String getAlias(Class<?> cls) { private String getAlias(Class<?> cls) {

View File

@ -66,9 +66,7 @@ public abstract class AbstractCacheTestCase extends AbstractPersistenceTestCase
public OpenJPAEntityManagerFactorySPI createEntityManagerFactory(String puName, public OpenJPAEntityManagerFactorySPI createEntityManagerFactory(String puName,
Map<String, Object> additionalProperties) { Map<String, Object> additionalProperties) {
Map<String, Object> propertiesMap = getPropertiesMap("openjpa.DataCache", "true", Map<String, Object> propertiesMap = getPropertiesMap( persistentTypes,
"openjpa.QueryCache", "true",
"openjpa.RemoteCommitProvider", "sjvm", persistentTypes,
"openjpa.jdbc.JDBCListeners", new JDBCListener [] { getListener() }); "openjpa.jdbc.JDBCListeners", new JDBCListener [] { getListener() });
if (additionalProperties != null) { if (additionalProperties != null) {
Set<String> keys = additionalProperties.keySet(); Set<String> keys = additionalProperties.keySet();

View File

@ -0,0 +1,28 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.openjpa.persistence.cache.jpa;
import org.apache.openjpa.datacache.ConcurrentDataCache;
public class DataCacheTestExtension extends ConcurrentDataCache {
private static final long serialVersionUID = 1L;
}

View File

@ -23,13 +23,19 @@ import java.util.List;
import javax.persistence.Cache; import javax.persistence.Cache;
import org.apache.openjpa.datacache.ConcurrentDataCache;
import org.apache.openjpa.lib.jdbc.JDBCListener; import org.apache.openjpa.lib.jdbc.JDBCListener;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI; import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
import org.apache.openjpa.persistence.test.FilteringJDBCListener; import org.apache.openjpa.persistence.test.FilteringJDBCListener;
/*
* When shared-cache-mode is set to ALL, all entities will be cached.
* If the DataCache is not configured, the default values will be used.
* For example, CacheSize will be set to default value 1000.
*/
public class TestCacheModeAll extends AbstractCacheModeTestCase { public class TestCacheModeAll extends AbstractCacheModeTestCase {
private static Cache cache = null; protected static Cache cache = null;
private static List<String> sql = new ArrayList<String>(); private static List<String> sql = new ArrayList<String>();
private static JDBCListener listener; private static JDBCListener listener;
@ -41,6 +47,11 @@ public class TestCacheModeAll extends AbstractCacheModeTestCase {
if (emf == null) { if (emf == null) {
emf = createEntityManagerFactory("cache-mode-all",null); emf = createEntityManagerFactory("cache-mode-all",null);
assertNotNull(emf); assertNotNull(emf);
ConcurrentDataCache dataCache = (ConcurrentDataCache) emf.getConfiguration()
.getDataCacheManagerInstance().getDataCache("default");
assertNotNull(dataCache);
assertEquals(1000, dataCache.getCacheSize());
assertEquals("true", emf.getConfiguration().getDataCache());
cache = emf.getCache(); cache = emf.getCache();
assertNotNull(cache); assertNotNull(cache);
} }

View File

@ -0,0 +1,56 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.openjpa.persistence.cache.jpa;
import java.util.HashMap;
import java.util.Map;
import org.apache.openjpa.datacache.ConcurrentDataCache;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
/*
* When shared-cache-mode is set to ALL, all entities will be cached no matter
* what is the customized DataCache setting. The other DataCache
* config settings like CacheSize will be used to config the data cache.
*/
public class TestCacheModeAllDataCacheCustomized extends TestCacheModeAll {
@Override
public OpenJPAEntityManagerFactorySPI getEntityManagerFactory() {
Map<String, Object> props = new HashMap<String, Object>();
props.put("openjpa.DataCache",
"org.apache.openjpa.persistence.cache.jpa.DataCacheTestExtension(CacheSize=5000, "
+ "ExcludedTypes=org.apache.openjpa.persistence.cache.jpa.model.UncacheableEntity)");
props.put("openjpa.RemoteCommitProvider", "sjvm");
if (emf == null) {
emf = createEntityManagerFactory("cache-mode-all", props);
assertNotNull(emf);
ConcurrentDataCache dataCache =
(ConcurrentDataCache) emf.getConfiguration().getDataCacheManagerInstance().getDataCache("default");
assertNotNull(dataCache);
assertEquals(5000, dataCache.getCacheSize());
assertEquals("org.apache.openjpa.persistence.cache.jpa.DataCacheTestExtension(CacheSize=5000, "
+ "ExcludedTypes=org.apache.openjpa.persistence.cache.jpa.model.UncacheableEntity)", emf
.getConfiguration().getDataCache());
cache = emf.getCache();
assertNotNull(cache);
}
return emf;
}
}

View File

@ -0,0 +1,57 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.openjpa.persistence.cache.jpa;
import java.util.HashMap;
import java.util.Map;
import org.apache.openjpa.datacache.ConcurrentDataCache;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
/*
* When shared-cache-mode is set to ALL, all entities will be cached no matter
* what is DataCache Types/ExcludedTypes setting. The other DataCache
* config settings like CacheSize will be used to config the data cache.
*/
public class TestCacheModeAllDataCacheTrue extends TestCacheModeAll {
@Override
public OpenJPAEntityManagerFactorySPI getEntityManagerFactory() {
Map<String, Object> props = new HashMap<String, Object>();
props.put("openjpa.DataCache", "true(CacheSize=5000, "
+ "ExcludedTypes=org.apache.openjpa.persistence.cache.jpa.model.UncacheableEntity)");
props.put("openjpa.RemoteCommitProvider", "sjvm");
if (emf == null) {
emf = createEntityManagerFactory("cache-mode-all", props);
assertNotNull(emf);
ConcurrentDataCache dataCache =
(ConcurrentDataCache) emf.getConfiguration().getDataCacheManagerInstance().getDataCache("default");
assertNotNull(dataCache);
assertEquals(5000, dataCache.getCacheSize());
assertEquals("true(CacheSize=5000, ExcludedTypes="
+ "org.apache.openjpa.persistence.cache.jpa.model.UncacheableEntity)", emf.getConfiguration()
.getDataCache());
cache = emf.getCache();
assertNotNull(cache);
}
return emf;
}
}

View File

@ -35,7 +35,7 @@ import org.apache.openjpa.persistence.test.FilteringJDBCListener;
public class TestCacheModeDisableSelective extends AbstractCacheModeTestCase { public class TestCacheModeDisableSelective extends AbstractCacheModeTestCase {
private static Cache cache = null; protected static Cache cache = null;
private static List<String> sql = new ArrayList<String>(); private static List<String> sql = new ArrayList<String>();
private static JDBCListener listener; private static JDBCListener listener;
@ -49,6 +49,7 @@ public class TestCacheModeDisableSelective extends AbstractCacheModeTestCase {
if (emf == null) { if (emf == null) {
emf = createEntityManagerFactory("cache-mode-disable", null); emf = createEntityManagerFactory("cache-mode-disable", null);
assertNotNull(emf); assertNotNull(emf);
assertEquals("true", emf.getConfiguration().getDataCache());
cache = emf.getCache(); cache = emf.getCache();
assertNotNull(cache); assertNotNull(cache);
} }

View File

@ -18,6 +18,9 @@
*/ */
package org.apache.openjpa.persistence.cache.jpa; package org.apache.openjpa.persistence.cache.jpa;
/*
* When both shared-cache-mode and dataCache are not set, caching will be off.
*/
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -41,6 +44,7 @@ public class TestCacheModeEmpty extends AbstractCacheModeTestCase {
if (emf == null) { if (emf == null) {
emf = createEntityManagerFactory("cache-mode-empty", null); emf = createEntityManagerFactory("cache-mode-empty", null);
assertNotNull(emf); assertNotNull(emf);
assertEquals("false", emf.getConfiguration().getDataCache());
cache = emf.getCache(); cache = emf.getCache();
assertNotNull(cache); assertNotNull(cache);
} }
@ -59,15 +63,15 @@ public class TestCacheModeEmpty extends AbstractCacheModeTestCase {
} }
public void testCacheables() { public void testCacheables() {
assertCacheables(cache, true); assertCacheables(cache, false);
} }
public void testUncacheables() { public void testUncacheables() {
assertUncacheables(cache, true); assertUncacheables(cache, false);
} }
public void testUnspecified() { public void testUnspecified() {
assertUnspecified(cache, true); assertUnspecified(cache, false);
} }
@Override @Override
@ -79,4 +83,9 @@ public class TestCacheModeEmpty extends AbstractCacheModeTestCase {
protected Class<?>[] getExpectedNotInCache() { protected Class<?>[] getExpectedNotInCache() {
return expectedNotInCache; return expectedNotInCache;
} }
@Override
public boolean getCacheEnabled() {
return false;
}
} }

View File

@ -0,0 +1,52 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.openjpa.persistence.cache.jpa;
import java.util.HashMap;
import java.util.Map;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
/*
* When ENABLE_SELECTIVE is set for the shared-cache-mode element and an entity is marked as cacheable(true),
* the entity will be cached even though DataCache ExcludedTypes indicate it should be excluded
* since shared-cache-mode take the precedence.
*/
public class TestCacheModeEnableSelectedDataCacheTrue extends TestCacheModeEnableSelective{
@Override
public OpenJPAEntityManagerFactorySPI getEntityManagerFactory() {
Map<String,Object> props = new HashMap<String,Object>();
//exclude types will be ignored since shared cache mode take precedence
props.put("openjpa.DataCache", "true(ExcludedTypes=" +
"org.apache.openjpa.persistence.cache.jpa.model.CacheableEntity)");
props.put("openjpa.RemoteCommitProvider", "sjvm");
if (emf == null) {
emf = createEntityManagerFactory("cache-mode-enable", props);
assertNotNull(emf);
assertEquals("true(ExcludedTypes=" +
"org.apache.openjpa.persistence.cache.jpa.model.CacheableEntity)",
emf.getConfiguration().getDataCache());
cache = emf.getCache();
assertNotNull(cache);
}
return emf;
}
}

View File

@ -35,7 +35,7 @@ import org.apache.openjpa.persistence.test.FilteringJDBCListener;
public class TestCacheModeEnableSelective extends AbstractCacheModeTestCase { public class TestCacheModeEnableSelective extends AbstractCacheModeTestCase {
private static Cache cache = null; protected static Cache cache = null;
private static List<String> sql = new ArrayList<String>(); private static List<String> sql = new ArrayList<String>();
private static JDBCListener listener; private static JDBCListener listener;
@ -49,6 +49,7 @@ public class TestCacheModeEnableSelective extends AbstractCacheModeTestCase {
if (emf == null) { if (emf == null) {
emf = createEntityManagerFactory("cache-mode-enable", null); emf = createEntityManagerFactory("cache-mode-enable", null);
assertNotNull(emf); assertNotNull(emf);
assertEquals("true", emf.getConfiguration().getDataCache());
cache = emf.getCache(); cache = emf.getCache();
assertNotNull(cache); assertNotNull(cache);
} }

View File

@ -32,9 +32,7 @@ public class TestCacheModeInvalid extends AbstractCacheTestCase {
public void testInvalidElement() { public void testInvalidElement() {
boolean exceptionCaught = false; boolean exceptionCaught = false;
try { try {
Map<String, Object> propertiesMap = getPropertiesMap("openjpa.DataCache", "true", Map<String, Object> propertiesMap = getPropertiesMap(persistentTypes,
"openjpa.QueryCache", "true",
"openjpa.RemoteCommitProvider", "sjvm", persistentTypes,
"openjpa.jdbc.JDBCListeners", new JDBCListener [] { getListener() }); "openjpa.jdbc.JDBCListeners", new JDBCListener [] { getListener() });
emf = (OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.createEntityManagerFactory("cache-mode-invalid", emf = (OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.createEntityManagerFactory("cache-mode-invalid",
"META-INF/caching-persistence-invalid.xml", propertiesMap ); "META-INF/caching-persistence-invalid.xml", propertiesMap );

View File

@ -27,9 +27,12 @@ import org.apache.openjpa.lib.jdbc.JDBCListener;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI; import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
import org.apache.openjpa.persistence.test.FilteringJDBCListener; import org.apache.openjpa.persistence.test.FilteringJDBCListener;
/*
* When shared-cache-mode is NONE and dataCache is not set, caching will be off.
*/
public class TestCacheModeNone extends AbstractCacheModeTestCase { public class TestCacheModeNone extends AbstractCacheModeTestCase {
private static Cache cache = null; protected static Cache cache = null;
private static List<String> sql = new ArrayList<String>(); private static List<String> sql = new ArrayList<String>();
private static JDBCListener listener; private static JDBCListener listener;
@ -40,6 +43,7 @@ public class TestCacheModeNone extends AbstractCacheModeTestCase {
public OpenJPAEntityManagerFactorySPI getEntityManagerFactory() { public OpenJPAEntityManagerFactorySPI getEntityManagerFactory() {
if (emf == null) { if (emf == null) {
emf = createEntityManagerFactory("cache-mode-none",null); emf = createEntityManagerFactory("cache-mode-none",null);
assertEquals("false", emf.getConfiguration().getDataCache());
assertNotNull(emf); assertNotNull(emf);
cache = emf.getCache(); cache = emf.getCache();
assertNotNull(cache); assertNotNull(cache);

View File

@ -0,0 +1,47 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.openjpa.persistence.cache.jpa;
import java.util.HashMap;
import java.util.Map;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
public class TestCacheModeNoneDataCacheCustomized extends TestCacheModeNone {
@Override
public OpenJPAEntityManagerFactorySPI getEntityManagerFactory() {
Map<String, Object> props = new HashMap<String, Object>();
props.put("openjpa.DataCache",
"org.apache.openjpa.persistence.cache.jpa.DataCacheTestExtension(CacheSize=5000, "
+ "ExcludedTypes=org.apache.openjpa.persistence.cache.jpa.model.UncacheableEntity)");
props.put("openjpa.RemoteCommitProvider", "sjvm");
if (emf == null) {
emf = createEntityManagerFactory("cache-mode-none", props);
assertNotNull(emf);
assertEquals("org.apache.openjpa.persistence.cache.jpa.DataCacheTestExtension(CacheSize=5000, "
+ "ExcludedTypes=org.apache.openjpa.persistence.cache.jpa.model.UncacheableEntity)", emf
.getConfiguration().getDataCache());
cache = emf.getCache();
assertNotNull(cache);
}
return emf;
}
}

View File

@ -0,0 +1,47 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.openjpa.persistence.cache.jpa;
import java.util.HashMap;
import java.util.Map;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
/*
* Caching is off when shared cache mode is set to NONE no matter
* dataCache is set to true or not.
* */
public class TestCacheModeNoneDataCacheTrue extends TestCacheModeNone{
@Override
public OpenJPAEntityManagerFactorySPI getEntityManagerFactory() {
Map<String,Object> props = new HashMap<String,Object>();
props.put("openjpa.DataCache", "true");
props.put("openjpa.RemoteCommitProvider", "sjvm");
if (emf == null) {
emf = createEntityManagerFactory("cache-mode-none",props);
assertNotNull(emf);
assertEquals("true", emf.getConfiguration().getDataCache());
cache = emf.getCache();
assertNotNull(cache);
}
return emf;
}
}

View File

@ -27,6 +27,9 @@ import org.apache.openjpa.lib.jdbc.JDBCListener;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI; import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
import org.apache.openjpa.persistence.test.FilteringJDBCListener; import org.apache.openjpa.persistence.test.FilteringJDBCListener;
/*
* When shared-cache-mode is UNSPECIFIED and dataCache is not set, caching will be off.
*/
public class TestCacheModeUnspecified extends AbstractCacheModeTestCase { public class TestCacheModeUnspecified extends AbstractCacheModeTestCase {
private static Cache cache = null; private static Cache cache = null;
@ -41,6 +44,7 @@ public class TestCacheModeUnspecified extends AbstractCacheModeTestCase {
if (emf == null) { if (emf == null) {
emf = createEntityManagerFactory("cache-mode-unspecified", null); emf = createEntityManagerFactory("cache-mode-unspecified", null);
assertNotNull(emf); assertNotNull(emf);
assertEquals("false", emf.getConfiguration().getDataCache());
cache = emf.getCache(); cache = emf.getCache();
assertNotNull(cache); assertNotNull(cache);
} }
@ -59,15 +63,15 @@ public class TestCacheModeUnspecified extends AbstractCacheModeTestCase {
} }
public void testCacheables() { public void testCacheables() {
assertCacheables(cache, true); assertCacheables(cache, false);
} }
public void testUncacheables() { public void testUncacheables() {
assertUncacheables(cache, true); assertUncacheables(cache, false);
} }
public void testUnspecified() { public void testUnspecified() {
assertUnspecified(cache, true); assertUnspecified(cache, false);
} }
@Override @Override
@ -79,4 +83,9 @@ public class TestCacheModeUnspecified extends AbstractCacheModeTestCase {
protected Class<?>[] getExpectedNotInCache() { protected Class<?>[] getExpectedNotInCache() {
return expectedNotInCache; return expectedNotInCache;
} }
@Override
public boolean getCacheEnabled() {
return false;
}
} }

View File

@ -0,0 +1,90 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.openjpa.persistence.cache.jpa;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.persistence.Cache;
import org.apache.openjpa.lib.jdbc.JDBCListener;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
import org.apache.openjpa.persistence.test.FilteringJDBCListener;
/*
* When shared-cache-mode is UNSPECIFIED and dataCache is true, caching will be on.
*/
public class TestCacheModeUnspecifiedDataCacheTrue extends AbstractCacheModeTestCase{
private static Cache cache = null;
private static List<String> sql = new ArrayList<String>();
private static JDBCListener listener;
private static Class<?>[] expectedInCache = persistentTypes;
private static Class<?>[] expectedNotInCache = {};
@Override
public OpenJPAEntityManagerFactorySPI getEntityManagerFactory() {
Map<String,Object> props = new HashMap<String,Object>();
props.put("openjpa.DataCache", "true");
props.put("openjpa.RemoteCommitProvider", "sjvm");
if (emf == null) {
emf = createEntityManagerFactory("cache-mode-unspecified", props);
assertNotNull(emf);
cache = emf.getCache();
assertNotNull(cache);
}
return emf;
}
public JDBCListener getListener() {
if (listener == null) {
listener = new FilteringJDBCListener(getSql());
}
return listener;
}
public List<String> getSql() {
return sql;
}
public void testCacheables() {
assertCacheables(cache, true);
}
public void testUncacheables() {
assertUncacheables(cache, true);
}
public void testUnspecified() {
assertUnspecified(cache, true);
}
@Override
protected Class<?>[] getExpectedInCache() {
return expectedInCache;
}
@Override
protected Class<?>[] getExpectedNotInCache() {
return expectedNotInCache;
}
}

View File

@ -29,6 +29,9 @@ import org.apache.openjpa.lib.jdbc.JDBCListener;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI; import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
import org.apache.openjpa.persistence.test.FilteringJDBCListener; import org.apache.openjpa.persistence.test.FilteringJDBCListener;
/*
* When sharedCache.mode is UNSPECIFIED and dataCache is not set, caching will be off.
*/
public class TestPropertyCacheModeUnspecified extends AbstractCacheModeTestCase { public class TestPropertyCacheModeUnspecified extends AbstractCacheModeTestCase {
private static Cache cache = null; private static Cache cache = null;
@ -63,15 +66,15 @@ public class TestPropertyCacheModeUnspecified extends AbstractCacheModeTestCase
} }
public void testCacheables() { public void testCacheables() {
assertCacheables(cache, true); assertCacheables(cache, false);
} }
public void testUncacheables() { public void testUncacheables() {
assertUncacheables(cache, true); assertUncacheables(cache, false);
} }
public void testUnspecified() { public void testUnspecified() {
assertUnspecified(cache, true); assertUnspecified(cache, false);
} }
@Override @Override
@ -83,4 +86,9 @@ public class TestPropertyCacheModeUnspecified extends AbstractCacheModeTestCase
protected Class<?>[] getExpectedNotInCache() { protected Class<?>[] getExpectedNotInCache() {
return expectedNotInCache; return expectedNotInCache;
} }
@Override
public boolean getCacheEnabled() {
return false;
}
} }

View File

@ -699,11 +699,28 @@ public class PersistenceProductDerivation
// those. // those.
if (conf instanceof OpenJPAConfiguration) { if (conf instanceof OpenJPAConfiguration) {
OpenJPAConfiguration oconf = (OpenJPAConfiguration) conf; OpenJPAConfiguration oconf = (OpenJPAConfiguration) conf;
String dataCache = oconf.getDataCache();
String sharedDataCacheMode = oconf.getDataCacheMode();
if (DataCacheMode.NONE.toString().equals(sharedDataCacheMode)
&& dataCache != null && !"false".equals(dataCache)) {
Log log = conf.getConfigurationLog();
if (log.isWarnEnabled()) {
log.warn(_loc.get("shared-cache-mode-take-precedence", dataCache));
}
}
if ((dataCache == null || "false".equals(dataCache))
&& !DataCacheMode.NONE.toString().equals(sharedDataCacheMode)
&& !DataCacheMode.UNSPECIFIED.toString().equals(sharedDataCacheMode)){
oconf.setDataCache("true");
}
// If the datacache is enabled, make sure we have a RemoteCommitProvider // If the datacache is enabled, make sure we have a RemoteCommitProvider
String dc = oconf.getDataCache();
String rcp = oconf.getRemoteCommitProvider(); String rcp = oconf.getRemoteCommitProvider();
dataCache = oconf.getDataCache();
// If the datacache is set and is something other than false // If the datacache is set and is something other than false
if (dc != null && !"false".equals(dc)) { if (dataCache != null && !"false".equals(dataCache)) {
// If RCP is null or empty, set it to sjvm. // If RCP is null or empty, set it to sjvm.
if (rcp == null || "".equals(rcp)) { if (rcp == null || "".equals(rcp)) {
oconf.setRemoteCommitProvider("sjvm"); oconf.setRemoteCommitProvider("sjvm");

View File

@ -254,3 +254,5 @@ managed PersistenceUnit "{0}". Each EntityManager created for this PersistenceUn
connection will not be released until the EntityManager is closed. If the application uses container managed \ connection will not be released until the EntityManager is closed. If the application uses container managed \
EntityManagers this property should not be used because these EntityManagers may remain open for extended periods of \ EntityManagers this property should not be used because these EntityManagers may remain open for extended periods of \
time. time.
shared-cache-mode-take-precedence: The DataCache is set to {0} while the shared-cache-mode Element or \
javax.persistence.sharedCache.mode property is set to NONE. The shared-cache-mode take the precedence and caching will be disabled.

View File

@ -134,6 +134,16 @@ a distributed environment, as caches in different JVMs or created from different
Data Cache Configuration Data Cache Configuration
</title> </title>
<para> <para>
There are two ways to enable the basic single-factory cache. One is using
<link linkend="openjpa.DataCache"><literal>openjpa.DataCache</literal></link>
property, the other is using JPA standard shared-cache-mode element or the
javax.persistence.sharedCache.mode property.
</para>
<section id="ref_guide_data_cache">
<title>
openjpa.DataCache Configuration
</title>
<para>
To enable the basic single-factory cache set the To enable the basic single-factory cache set the
<link linkend="openjpa.DataCache"><literal>openjpa.DataCache</literal></link> <link linkend="openjpa.DataCache"><literal>openjpa.DataCache</literal></link>
property to <literal>true</literal>: property to <literal>true</literal>:
@ -353,10 +363,69 @@ an UPDATE or DELETE statement. The default for the value is <literal>true</liter
<programlisting>&lt;property name="openjpa.DataCache" value="true(EvictOnBulkUpdate=false)"/&gt;</programlisting> <programlisting>&lt;property name="openjpa.DataCache" value="true(EvictOnBulkUpdate=false)"/&gt;</programlisting>
</para> </para>
</example> </example>
</section>
<section id="ref_guide_shared_cache_mode_integration">
<title>
Integration with JPA standard shared cache mode
</title>
<para>
JPA 2.0 specification introduced the standard data cache configuration through the shared-cache-mode element or javax.persistence.
sharedCache.mode property.
</para>
<para>
When only the shared cache mode is configured to turn on the caching, the default data cache setting will be used. For example the
cache size will be set to default 1000.
</para>
<para>
When the shared cache mode and openjpa.DataCache are both configured, the JPA standard shared cache mode
configuration takes the precedence.
</para>
<para>
If the shared cache mode is to turn on the caching, the cache setting configured through openjpa.DataCache
, like cacheSize and SoftReferenceSize, will be used to initialize or manage the cache. The Types and ExcludeTypes
property in openjpa.DataCache will be ingnored since the shared cache mode in conjunction with the javax.persistence.Cacheable
annotation already defines what will be cached.
</para>
<example id="shared-cache-mode-none">
<para>
<programlisting>
&lt;property name="openjpa.DataCache" value="true"/&gt;
&lt;property name="javax.persistence.sharedCache.mode" value="NONE"/&gt;
</programlisting>
</para>
<para>
When the shared cache mode is set to NONE, the data cache will be disabled no matter how openjpa.DataCache is configured.
</para>
</example>
<example id="shared-cache-mode-all">
<para>
<programlisting>
&lt;property name="openjpa.DataCache" value="true(ExcludedTypes=foo.bar.Person;foo.bar.Employee)"/&gt;
&lt;property name="javax.persistence.sharedCache.mode" value="ALL"/&gt;
</programlisting>
</para>
<para>
When the shared cache mode is set to ALL, all entities will be cached no matter how openjpa.DataCache is configured.
</para>
</example>
<example id="shared-cache-mode-enable-selective">
<para>
<programlisting>
&lt;property name="openjpa.DataCache" value="true(ExcludedTypes=foo.bar.Person;foo.bar.Employee)"/&gt;
&lt;property name="javax.persistence.sharedCache.mode" value="ENABLE_SELECTIVE"/&gt;
</programlisting>
</para>
<para>
When the shared cache mode set to ENABLE_SELECTIVE, the entities with Cacheable(true) anotation will be cached.
ExcludedTypes will be ignored.
</para>
</example>
</section>
<section id="ref_guide_cache_distribution"> <section id="ref_guide_cache_distribution">
<title>Distributing instances across cache partitions</title> <title>Distributing instances across cache partitions</title>
<para> <para>
OpenJPA also supports a partitioned cache configuration where the cached OpenJPA also supports a partitioned cache configuration where the cached
instances can be distributed across partitions by an application-defined instances can be distributed across partitions by an application-defined
policy. Each partition behaves as a data cache by itself, identified by its name and can policy. Each partition behaves as a data cache by itself, identified by its name and can