diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractDataCache.java b/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractDataCache.java index 6c8780a2a..f784b4c99 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractDataCache.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/AbstractDataCache.java @@ -523,20 +523,32 @@ public abstract class AbstractDataCache extends AbstractConcurrentEventManager public void setTypes(Set 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) { _includedTypes = StringUtils.isEmpty(types) ? null : new HashSet(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 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) { _excludedTypes = StringUtils.isEmpty(types) ? null : new HashSet(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) { diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java b/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java index 6d8aa2369..de5d79471 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java @@ -143,7 +143,7 @@ public class DataCacheStoreManager continue; mods = getModifications(modMap, cache); - data = newPCData(sm); + data = newPCData(sm, cache); data.store(sm); mods.additions.add(new PCDataHolder(data, sm)); CacheStatistics stats = cache.getStatistics(); @@ -178,7 +178,7 @@ public class DataCacheStoreManager // dirty, but maybe it got dropped from the cache in the // interim if (data == null) { - data = newPCData(sm); + data = newPCData(sm, cache); data.store(sm); mods.newUpdates.add(new PCDataHolder(data, sm)); } else { @@ -420,7 +420,7 @@ public class DataCacheStoreManager // initial load of the data. boolean isNew = data == null; if (isNew) { - data = newPCData(sm); + data = newPCData(sm, cache); } data.store(sm); if (isNew) { @@ -626,7 +626,7 @@ public class DataCacheStoreManager isNew = data == null; if (isNew) - data = newPCData(sm); + data = newPCData(sm, cache); if (fields == null) data.store(sm); else @@ -780,15 +780,15 @@ public class DataCacheStoreManager _ctx.getConfiguration().getRemoteCommitEventManager() .fireLocalStaleNotification(oid); } - + /** * 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(); if (_gen != null) 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()); } /** diff --git a/openjpa-kernel/src/main/resources/org/apache/openjpa/datacache/localizer.properties b/openjpa-kernel/src/main/resources/org/apache/openjpa/datacache/localizer.properties index 0b7123c55..3680e7639 100644 --- a/openjpa-kernel/src/main/resources/org/apache/openjpa/datacache/localizer.properties +++ b/openjpa-kernel/src/main/resources/org/apache/openjpa/datacache/localizer.properties @@ -113,5 +113,7 @@ partition-cache-default-partition: You have specified name "{0}" for a \ partition in the configuration "{0}". The partition name matches the default \ name reserved by OpenJPA for internal use and hence can not be used. 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. - \ No newline at end of file + 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. diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/AbstractCacheModeTestCase.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/AbstractCacheModeTestCase.java index e0447a217..6f5aafa9b 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/AbstractCacheModeTestCase.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/AbstractCacheModeTestCase.java @@ -203,28 +203,30 @@ public abstract class AbstractCacheModeTestCase extends AbstractCacheTestCase { * */ public void testRetrieveModeUse() { - assertNoSql(new Action() { - public void run() { - EntityManager em = getEntityManagerFactory().createEntityManager(); - em.setProperty(RETRIEVE_MODE_PROP, CacheRetrieveMode.USE); - for (Class cls : getExpectedInCache()) { - assertCached(getEntityManagerFactory().getCache(), cls, 1, true); - assertNotNull(em.find(cls, 1)); + if (getCacheEnabled()) { + assertNoSql(new Action() { + public void run() { + EntityManager em = getEntityManagerFactory().createEntityManager(); + em.setProperty(RETRIEVE_MODE_PROP, CacheRetrieveMode.USE); + for (Class cls : getExpectedInCache()) { + assertCached(getEntityManagerFactory().getCache(), cls, 1, true); + assertNotNull(em.find(cls, 1)); + } + em.close(); } - em.close(); - } - }); - assertSqlInc(new Action() { - public void run() { - EntityManager em = getEntityManagerFactory().createEntityManager(); - em.setProperty(RETRIEVE_MODE_PROP, CacheRetrieveMode.USE); - for (Class cls : getExpectedNotInCache()) { - assertCached(getEntityManagerFactory().getCache(), cls, 1, false); - assertNotNull(em.find(cls, 1)); + }); + assertSqlInc(new Action() { + public void run() { + EntityManager em = getEntityManagerFactory().createEntityManager(); + em.setProperty(RETRIEVE_MODE_PROP, CacheRetrieveMode.USE); + for (Class cls : getExpectedNotInCache()) { + assertCached(getEntityManagerFactory().getCache(), cls, 1, false); + assertNotNull(em.find(cls, 1)); + } + em.close(); } - em.close(); - } - }, getExpectedNotInCache().length); + }, getExpectedNotInCache().length); + } } public void updateAndFind(Class classToUpdate, int idToUpdate, @@ -404,45 +406,50 @@ public abstract class AbstractCacheModeTestCase extends AbstractCacheTestCase { } public void testResultsFromQueryAreInCache() { - // clear cache - getEntityManagerFactory().getStoreCache().evictAll(); - getEntityManagerFactory().getQueryResultCache().evictAll(); + if (getCacheEnabled()) { + // clear cache + getEntityManagerFactory().getStoreCache().evictAll(); + getEntityManagerFactory().getQueryResultCache().evictAll(); - EntityManager em = getEntityManagerFactory().createEntityManager(); - String query; - for(Class cls : persistentTypes) { - query = "Select e from " + getAlias(cls) + " e"; - List res = em.createQuery(query).getResultList(); - 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 ) ; + EntityManager em = getEntityManagerFactory().createEntityManager(); + String query; + for(Class cls : persistentTypes) { + query = "Select e from " + getAlias(cls) + " e"; + List res = em.createQuery(query).getResultList(); + 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 ) ; + } + for(Class cls : getExpectedInCache()) { + assertCached(getEntityManagerFactory().getCache(), cls, 1, true); + } + + for(Class cls : getExpectedNotInCache()) { + assertCached(getEntityManagerFactory().getCache(), cls, 1, false); + } + em.close(); } - for(Class cls : getExpectedInCache()) { - assertCached(getEntityManagerFactory().getCache(), cls, 1, true); - } - - for(Class cls : getExpectedNotInCache()) { - assertCached(getEntityManagerFactory().getCache(), cls, 1, false); - } - em.close(); } public void testResultsFromFindAreInCache() { - // clear cache - getEntityManagerFactory().getStoreCache().evictAll(); - getEntityManagerFactory().getQueryResultCache().evictAll(); + if (getCacheEnabled()) { + // clear cache + getEntityManagerFactory().getStoreCache().evictAll(); + getEntityManagerFactory().getQueryResultCache().evictAll(); - EntityManager em = getEntityManagerFactory().createEntityManager(); - for(Class cls : persistentTypes) { - assertNotNull(String.format("Expected to find %s::%d from database or from cache", cls, 1),em.find(cls, 1)); + EntityManager em = getEntityManagerFactory().createEntityManager(); + for(Class cls : persistentTypes) { + 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 : getExpectedNotInCache()) { + assertCached(getEntityManagerFactory().getCache(), cls, 1, false); + } + em.close(); } - for(Class cls : getExpectedInCache()) { - assertCached(getEntityManagerFactory().getCache(), cls, 1, true); - } - - for(Class cls : getExpectedNotInCache()) { - assertCached(getEntityManagerFactory().getCache(), cls, 1, false); - } - em.close(); } private String getAlias(Class cls) { diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/AbstractCacheTestCase.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/AbstractCacheTestCase.java index cc602bace..f34cd0cb4 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/AbstractCacheTestCase.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/AbstractCacheTestCase.java @@ -66,9 +66,7 @@ public abstract class AbstractCacheTestCase extends AbstractPersistenceTestCase public OpenJPAEntityManagerFactorySPI createEntityManagerFactory(String puName, Map additionalProperties) { - Map propertiesMap = getPropertiesMap("openjpa.DataCache", "true", - "openjpa.QueryCache", "true", - "openjpa.RemoteCommitProvider", "sjvm", persistentTypes, + Map propertiesMap = getPropertiesMap( persistentTypes, "openjpa.jdbc.JDBCListeners", new JDBCListener [] { getListener() }); if (additionalProperties != null) { Set keys = additionalProperties.keySet(); diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/DataCacheTestExtension.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/DataCacheTestExtension.java new file mode 100644 index 000000000..dc6c9d9d1 --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/DataCacheTestExtension.java @@ -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; + +} diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeAll.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeAll.java index 14f91b654..4b6170806 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeAll.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeAll.java @@ -23,13 +23,19 @@ import java.util.List; import javax.persistence.Cache; +import org.apache.openjpa.datacache.ConcurrentDataCache; 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 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 { - private static Cache cache = null; + protected static Cache cache = null; private static List sql = new ArrayList(); private static JDBCListener listener; @@ -41,6 +47,11 @@ public class TestCacheModeAll extends AbstractCacheModeTestCase { if (emf == null) { emf = createEntityManagerFactory("cache-mode-all",null); assertNotNull(emf); + ConcurrentDataCache dataCache = (ConcurrentDataCache) emf.getConfiguration() + .getDataCacheManagerInstance().getDataCache("default"); + assertNotNull(dataCache); + assertEquals(1000, dataCache.getCacheSize()); + assertEquals("true", emf.getConfiguration().getDataCache()); cache = emf.getCache(); assertNotNull(cache); } diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeAllDataCacheCustomized.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeAllDataCacheCustomized.java new file mode 100644 index 000000000..633cd4b6e --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeAllDataCacheCustomized.java @@ -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 props = new HashMap(); + 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; + } +} diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeAllDataCacheTrue.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeAllDataCacheTrue.java new file mode 100644 index 000000000..14f0134ab --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeAllDataCacheTrue.java @@ -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 props = new HashMap(); + 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; + } + +} diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeDisableSelective.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeDisableSelective.java index 28a45fe4b..e241bd8d1 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeDisableSelective.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeDisableSelective.java @@ -35,7 +35,7 @@ import org.apache.openjpa.persistence.test.FilteringJDBCListener; public class TestCacheModeDisableSelective extends AbstractCacheModeTestCase { - private static Cache cache = null; + protected static Cache cache = null; private static List sql = new ArrayList(); private static JDBCListener listener; @@ -49,6 +49,7 @@ public class TestCacheModeDisableSelective extends AbstractCacheModeTestCase { if (emf == null) { emf = createEntityManagerFactory("cache-mode-disable", null); assertNotNull(emf); + assertEquals("true", emf.getConfiguration().getDataCache()); cache = emf.getCache(); assertNotNull(cache); } diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeEmpty.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeEmpty.java index a962c8ccc..ec9411d9c 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeEmpty.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeEmpty.java @@ -18,6 +18,9 @@ */ 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.List; @@ -41,6 +44,7 @@ public class TestCacheModeEmpty extends AbstractCacheModeTestCase { if (emf == null) { emf = createEntityManagerFactory("cache-mode-empty", null); assertNotNull(emf); + assertEquals("false", emf.getConfiguration().getDataCache()); cache = emf.getCache(); assertNotNull(cache); } @@ -59,15 +63,15 @@ public class TestCacheModeEmpty extends AbstractCacheModeTestCase { } public void testCacheables() { - assertCacheables(cache, true); + assertCacheables(cache, false); } public void testUncacheables() { - assertUncacheables(cache, true); + assertUncacheables(cache, false); } public void testUnspecified() { - assertUnspecified(cache, true); + assertUnspecified(cache, false); } @Override @@ -79,4 +83,9 @@ public class TestCacheModeEmpty extends AbstractCacheModeTestCase { protected Class[] getExpectedNotInCache() { return expectedNotInCache; } + + @Override + public boolean getCacheEnabled() { + return false; + } } diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeEnableSelectedDataCacheTrue.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeEnableSelectedDataCacheTrue.java new file mode 100644 index 000000000..382033dd9 --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeEnableSelectedDataCacheTrue.java @@ -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 props = new HashMap(); + //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; + } + +} diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeEnableSelective.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeEnableSelective.java index f4a5bdbc0..ed71c9cfe 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeEnableSelective.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeEnableSelective.java @@ -35,7 +35,7 @@ import org.apache.openjpa.persistence.test.FilteringJDBCListener; public class TestCacheModeEnableSelective extends AbstractCacheModeTestCase { - private static Cache cache = null; + protected static Cache cache = null; private static List sql = new ArrayList(); private static JDBCListener listener; @@ -49,6 +49,7 @@ public class TestCacheModeEnableSelective extends AbstractCacheModeTestCase { if (emf == null) { emf = createEntityManagerFactory("cache-mode-enable", null); assertNotNull(emf); + assertEquals("true", emf.getConfiguration().getDataCache()); cache = emf.getCache(); assertNotNull(cache); } diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeInvalid.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeInvalid.java index fce18afd8..f946e419b 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeInvalid.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeInvalid.java @@ -32,9 +32,7 @@ public class TestCacheModeInvalid extends AbstractCacheTestCase { public void testInvalidElement() { boolean exceptionCaught = false; try { - Map propertiesMap = getPropertiesMap("openjpa.DataCache", "true", - "openjpa.QueryCache", "true", - "openjpa.RemoteCommitProvider", "sjvm", persistentTypes, + Map propertiesMap = getPropertiesMap(persistentTypes, "openjpa.jdbc.JDBCListeners", new JDBCListener [] { getListener() }); emf = (OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.createEntityManagerFactory("cache-mode-invalid", "META-INF/caching-persistence-invalid.xml", propertiesMap ); diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeNone.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeNone.java index b6ab0fe72..f8198a366 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeNone.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeNone.java @@ -27,9 +27,12 @@ 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 NONE and dataCache is not set, caching will be off. + */ public class TestCacheModeNone extends AbstractCacheModeTestCase { - private static Cache cache = null; + protected static Cache cache = null; private static List sql = new ArrayList(); private static JDBCListener listener; @@ -40,6 +43,7 @@ public class TestCacheModeNone extends AbstractCacheModeTestCase { public OpenJPAEntityManagerFactorySPI getEntityManagerFactory() { if (emf == null) { emf = createEntityManagerFactory("cache-mode-none",null); + assertEquals("false", emf.getConfiguration().getDataCache()); assertNotNull(emf); cache = emf.getCache(); assertNotNull(cache); diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeNoneDataCacheCustomized.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeNoneDataCacheCustomized.java new file mode 100644 index 000000000..1332edba1 --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeNoneDataCacheCustomized.java @@ -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 props = new HashMap(); + 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; + } +} diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeNoneDataCacheTrue.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeNoneDataCacheTrue.java new file mode 100644 index 000000000..6e00e33a6 --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeNoneDataCacheTrue.java @@ -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 props = new HashMap(); + 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; + } + +} diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeUnspecified.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeUnspecified.java index 58bbdc34a..c3f17cda5 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeUnspecified.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeUnspecified.java @@ -27,6 +27,9 @@ 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 not set, caching will be off. + */ public class TestCacheModeUnspecified extends AbstractCacheModeTestCase { private static Cache cache = null; @@ -41,6 +44,7 @@ public class TestCacheModeUnspecified extends AbstractCacheModeTestCase { if (emf == null) { emf = createEntityManagerFactory("cache-mode-unspecified", null); assertNotNull(emf); + assertEquals("false", emf.getConfiguration().getDataCache()); cache = emf.getCache(); assertNotNull(cache); } @@ -59,15 +63,15 @@ public class TestCacheModeUnspecified extends AbstractCacheModeTestCase { } public void testCacheables() { - assertCacheables(cache, true); + assertCacheables(cache, false); } public void testUncacheables() { - assertUncacheables(cache, true); + assertUncacheables(cache, false); } public void testUnspecified() { - assertUnspecified(cache, true); + assertUnspecified(cache, false); } @Override @@ -79,4 +83,9 @@ public class TestCacheModeUnspecified extends AbstractCacheModeTestCase { protected Class[] getExpectedNotInCache() { return expectedNotInCache; } + + @Override + public boolean getCacheEnabled() { + return false; + } } diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeUnspecifiedDataCacheTrue.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeUnspecifiedDataCacheTrue.java new file mode 100644 index 000000000..202ea8789 --- /dev/null +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestCacheModeUnspecifiedDataCacheTrue.java @@ -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 sql = new ArrayList(); + private static JDBCListener listener; + + private static Class[] expectedInCache = persistentTypes; + private static Class[] expectedNotInCache = {}; + + @Override + public OpenJPAEntityManagerFactorySPI getEntityManagerFactory() { + Map props = new HashMap(); + 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 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; + } +} diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestPropertyCacheModeUnspecified.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestPropertyCacheModeUnspecified.java index 64a33245e..bcc1979aa 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestPropertyCacheModeUnspecified.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/cache/jpa/TestPropertyCacheModeUnspecified.java @@ -29,6 +29,9 @@ import org.apache.openjpa.lib.jdbc.JDBCListener; import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI; 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 { private static Cache cache = null; @@ -63,15 +66,15 @@ public class TestPropertyCacheModeUnspecified extends AbstractCacheModeTestCase } public void testCacheables() { - assertCacheables(cache, true); + assertCacheables(cache, false); } public void testUncacheables() { - assertUncacheables(cache, true); + assertUncacheables(cache, false); } public void testUnspecified() { - assertUnspecified(cache, true); + assertUnspecified(cache, false); } @Override @@ -83,4 +86,9 @@ public class TestPropertyCacheModeUnspecified extends AbstractCacheModeTestCase protected Class[] getExpectedNotInCache() { return expectedNotInCache; } + + @Override + public boolean getCacheEnabled() { + return false; + } } diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java index 6cda70baa..2d178bf3e 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java @@ -699,11 +699,28 @@ public class PersistenceProductDerivation // those. if (conf instanceof OpenJPAConfiguration) { OpenJPAConfiguration oconf = (OpenJPAConfiguration) conf; - // If the datacache is enabled, make sure we have a RemoteCommitProvider - String dc = oconf.getDataCache(); + 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 String rcp = oconf.getRemoteCommitProvider(); + dataCache = oconf.getDataCache(); // 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 == null || "".equals(rcp)) { oconf.setRemoteCommitProvider("sjvm"); diff --git a/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties b/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties index 470e2d0bf..c75558202 100644 --- a/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties +++ b/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties @@ -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 \ EntityManagers this property should not be used because these EntityManagers may remain open for extended periods of \ 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. diff --git a/openjpa-project/src/doc/manual/ref_guide_caching.xml b/openjpa-project/src/doc/manual/ref_guide_caching.xml index e7cbabaf8..e8263fc20 100644 --- a/openjpa-project/src/doc/manual/ref_guide_caching.xml +++ b/openjpa-project/src/doc/manual/ref_guide_caching.xml @@ -134,6 +134,16 @@ a distributed environment, as caches in different JVMs or created from different Data Cache Configuration +There are two ways to enable the basic single-factory cache. One is using +openjpa.DataCache +property, the other is using JPA standard shared-cache-mode element or the +javax.persistence.sharedCache.mode property. + +
+ + openjpa.DataCache Configuration + + To enable the basic single-factory cache set the openjpa.DataCache property to true: @@ -352,11 +362,70 @@ an UPDATE or DELETE statement. The default for the value is true <property name="openjpa.DataCache" value="true(EvictOnBulkUpdate=false)"/> - + +
+
+ + Integration with JPA standard shared cache mode + + + JPA 2.0 specification introduced the standard data cache configuration through the shared-cache-mode element or javax.persistence. +sharedCache.mode property. + + + 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. + + + When the shared cache mode and openjpa.DataCache are both configured, the JPA standard shared cache mode + configuration takes the precedence. + + + 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. + + + + +<property name="openjpa.DataCache" value="true"/> +<property name="javax.persistence.sharedCache.mode" value="NONE"/> + + + + When the shared cache mode is set to NONE, the data cache will be disabled no matter how openjpa.DataCache is configured. + + + + + + +<property name="openjpa.DataCache" value="true(ExcludedTypes=foo.bar.Person;foo.bar.Employee)"/> +<property name="javax.persistence.sharedCache.mode" value="ALL"/> + + + + When the shared cache mode is set to ALL, all entities will be cached no matter how openjpa.DataCache is configured. + + + + + + +<property name="openjpa.DataCache" value="true(ExcludedTypes=foo.bar.Person;foo.bar.Employee)"/> +<property name="javax.persistence.sharedCache.mode" value="ENABLE_SELECTIVE"/> + + + + When the shared cache mode set to ENABLE_SELECTIVE, the entities with Cacheable(true) anotation will be cached. + ExcludedTypes will be ignored. + + +
Distributing instances across cache partitions - OpenJPA also supports a partitioned cache configuration where the cached 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