|
|
|
Pinaki Poddar
|
Author: ppoddar
Date: Wed Nov 4 21:18:38 2009 New Revision: 832874 URL: http://svn.apache.org/viewvc?rev=832874&view=rev Log: OPENJPA-1334: Refresh should ignore cache.retrieve.mode settings. Assorted changes in property processing for usability Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfiguration.java openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/Reflection.java openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/enhance/localizer.properties openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheBehavesIdentical.java openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/TestRefresh.java openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/JPAProperties.java openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceUnitInfoImpl.java openjpa/trunk/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfiguration.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfiguration.java?rev=832874&r1=832873&r2=832874&view=diff ============================================================================== --- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfiguration.java (original) +++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfiguration.java Wed Nov 4 21:18:38 2009 @@ -374,6 +374,8 @@ * The entities are never refreshed from DataCache if lock is being applied * (e.g. in a pessimistic transaction) and hence this setting only refers * to behavior when not locking. + * This flag can be used to overwrite RetrieveMode.BYPASS. + * By default, however, this falg is false. * * @since 1.2.0 */ Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java?rev=832874&r1=832873&r2=832874&view=diff ============================================================================== --- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java (original) +++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/datacache/DataCacheStoreManager.java Wed Nov 4 21:18:38 2009 @@ -387,8 +387,7 @@ public boolean load(OpenJPAStateManager sm, BitSet fields, FetchConfiguration fetch, int lockLevel, Object edata) { DataCache cache = _mgr.selectCache(sm); - if (cache == null || sm.isEmbedded() - || _ctx.getFetchConfiguration().getCacheRetrieveMode() == DataCacheRetrieveMode.BYPASS) + if (cache == null || sm.isEmbedded() || bypass(_ctx.getFetchConfiguration(), StoreManager.FORCE_LOAD_NONE)) return super.load(sm, fields, fetch, lockLevel, edata); DataCachePCData data = cache.get(sm.getObjectId()); @@ -410,11 +409,8 @@ public Collection<Object> loadAll(Collection<OpenJPAStateManager> sms, PCState state, int load, FetchConfiguration fetch, Object edata) { - if (isLocking(fetch) || - (!isLocking(fetch) && - (load == StoreManager.FORCE_LOAD_REFRESH) - && !_ctx.getConfiguration().getRefreshFromDataCache())) { - return super.loadAll(sms, state, load, fetch, edata); + if (bypass(fetch, load)) { + return super.loadAll(sms, state, load, fetch, edata); } Map<OpenJPAStateManager, BitSet> unloaded = null; @@ -528,7 +524,7 @@ } return failed; } - + /** * Helper method to add an unloaded instance to the given map. */ @@ -691,6 +687,24 @@ } /** + * Affirms if a load operation must bypass the L2 cache. + * If lock is active, always bypass. + * + */ + boolean bypass(FetchConfiguration fetch, int load) { + // Order of checks are important + if (isLocking(fetch)) + return true; + if (_ctx.getConfiguration().getRefreshFromDataCache()) + return false; + if (fetch.getCacheRetrieveMode() == DataCacheRetrieveMode.BYPASS) + return true; + if (load == StoreManager.FORCE_LOAD_REFRESH) + return true; + return false; + } + + /** * Return whether the context is locking loaded data. */ private boolean isLocking(FetchConfiguration fetch) { Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/Reflection.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/Reflection.java?rev=832874&r1=832873&r2=832874&view=diff ============================================================================== --- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/Reflection.java (original) +++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/Reflection.java Wed Nov 4 21:18:38 2009 @@ -34,6 +34,7 @@ import org.apache.openjpa.lib.util.Localizer; import org.apache.openjpa.lib.util.ReferenceMap; import org.apache.openjpa.lib.util.Reflectable; +import org.apache.openjpa.lib.util.Localizer.Message; import org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashMap; import org.apache.openjpa.util.GeneralException; import org.apache.openjpa.util.UserException; @@ -282,7 +283,7 @@ try { return field.get(target); } catch (Throwable t) { - throw wrapReflectionException(t); + throw wrapReflectionException(t, _loc.get("get-field", target, field)); } } @@ -327,9 +328,10 @@ /** * Wrap the given reflection exception as a runtime exception. */ - private static RuntimeException wrapReflectionException(Throwable t) { + private static RuntimeException wrapReflectionException(Throwable t, Message message) { if (t instanceof InvocationTargetException) - t = ((InvocationTargetException) t).getTargetException(); + t = ((InvocationTargetException) t).getTargetException(); + t.initCause(new IllegalArgumentException(message.getMessage())); if (t instanceof RuntimeException) return (RuntimeException) t; return new GeneralException(t); @@ -345,7 +347,7 @@ try { return field.getBoolean(target); } catch (Throwable t) { - throw wrapReflectionException(t); + throw wrapReflectionException(t, _loc.get("get-field", target, field)); } } @@ -359,7 +361,7 @@ try { return field.getByte(target); } catch (Throwable t) { - throw wrapReflectionException(t); + throw wrapReflectionException(t, _loc.get("get-field", target, field)); } } @@ -373,7 +375,7 @@ try { return field.getChar(target); } catch (Throwable t) { - throw wrapReflectionException(t); + throw wrapReflectionException(t, _loc.get("get-field", target, field)); } } @@ -387,7 +389,7 @@ try { return field.getDouble(target); } catch (Throwable t) { - throw wrapReflectionException(t); + throw wrapReflectionException(t, _loc.get("get-field", target, field)); } } @@ -401,7 +403,7 @@ try { return field.getFloat(target); } catch (Throwable t) { - throw wrapReflectionException(t); + throw wrapReflectionException(t, _loc.get("get-field", target, field)); } } @@ -415,7 +417,7 @@ try { return field.getInt(target); } catch (Throwable t) { - throw wrapReflectionException(t); + throw wrapReflectionException(t, _loc.get("get-field", target, field)); } } @@ -429,7 +431,7 @@ try { return field.getLong(target); } catch (Throwable t) { - throw wrapReflectionException(t); + throw wrapReflectionException(t, _loc.get("get-field", target, field)); } } @@ -443,7 +445,7 @@ try { return field.getShort(target); } catch (Throwable t) { - throw wrapReflectionException(t); + throw wrapReflectionException(t, _loc.get("get-field", target, field)); } } @@ -457,7 +459,7 @@ try { return getter.invoke(target, (Object[]) null); } catch (Throwable t) { - throw wrapReflectionException(t); + throw wrapReflectionException(t, _loc.get("get-method", target, getter)); } } @@ -535,7 +537,8 @@ try { field.set(target, value); } catch (Throwable t) { - throw wrapReflectionException(t); + throw wrapReflectionException(t, _loc.get("set-field", new Object[]{target, field, value, + value == null ? "" : value.getClass()})); } } @@ -549,7 +552,7 @@ try { field.setBoolean(target, value); } catch (Throwable t) { - throw wrapReflectionException(t); + throw wrapReflectionException(t, _loc.get("set-field", new Object[]{target, field, value, "boolean"})); } } @@ -563,7 +566,7 @@ try { field.setByte(target, value); } catch (Throwable t) { - throw wrapReflectionException(t); + throw wrapReflectionException(t, _loc.get("set-field", new Object[]{target, field, value, "byte"})); } } @@ -577,7 +580,7 @@ try { field.setChar(target, value); } catch (Throwable t) { - throw wrapReflectionException(t); + throw wrapReflectionException(t, _loc.get("set-field", new Object[]{target, field, value, "char"})); } } @@ -591,7 +594,7 @@ try { field.setDouble(target, value); } catch (Throwable t) { - throw wrapReflectionException(t); + throw wrapReflectionException(t, _loc.get("set-field", new Object[]{target, field, value, "double"})); } } @@ -605,7 +608,7 @@ try { field.setFloat(target, value); } catch (Throwable t) { - throw wrapReflectionException(t); + throw wrapReflectionException(t, _loc.get("set-field", new Object[]{target, field, value, "float"})); } } @@ -619,7 +622,7 @@ try { field.setInt(target, value); } catch (Throwable t) { - throw wrapReflectionException(t); + throw wrapReflectionException(t, _loc.get("set-field", new Object[]{target, field, value, "int"})); } } @@ -633,7 +636,7 @@ try { field.setLong(target, value); } catch (Throwable t) { - throw wrapReflectionException(t); + throw wrapReflectionException(t, _loc.get("set-field", new Object[]{target, field, value, "long"})); } } @@ -647,7 +650,7 @@ try { field.setShort(target, value); } catch (Throwable t) { - throw wrapReflectionException(t); + throw wrapReflectionException(t, _loc.get("set-field", new Object[]{target, field, value, "short"})); } } @@ -760,7 +763,8 @@ try { setter.invoke(target, new Object[] { value }); } catch (Throwable t) { - throw wrapReflectionException(t); + throw wrapReflectionException(t, _loc.get("set-method", new Object[]{target, setter, value, + value == null ? "" : value.getClass()})); } } @@ -831,16 +835,16 @@ * it is ignored. * */ - public static Set<String> getBeanStylePropertyNames(Class c) { + public static Set<String> getBeanStylePropertyNames(Class<?> c) { if (c == null) - return Collections.EMPTY_SET; + return Collections.emptySet(); Set<String> result = beanPropertiesNameCache.get(c); if (result != null) { return result; } Method[] methods = c.getMethods(); if (methods == null || methods.length < 2) - return Collections.EMPTY_SET; + return Collections.emptySet(); result = new TreeSet<String>(); for (Method m : methods) { if (m.getName().startsWith("get")) { @@ -848,9 +852,9 @@ continue; String prop = StringUtils.capitalize(m.getName() .substring("get".length())); - Class rtype = m.getReturnType(); + Class<?> rtype = m.getReturnType(); try { - Method setter = c.getMethod("set"+prop, new Class[]{rtype}); + Method setter = c.getMethod("set"+prop, new Class<?>[]{rtype}); if (setter.getReturnType() == void.class || setter.getReturnType().isAssignableFrom(c)) result.add(prop); Modified: openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/enhance/localizer.properties URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/enhance/localizer.properties?rev=832874&r1=832873&r2=832874&view=diff ============================================================================== --- openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/enhance/localizer.properties (original) +++ openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/enhance/localizer.properties Wed Nov 4 21:18:38 2009 @@ -211,4 +211,7 @@ to creating any Entities. temp-file-creation: The temporary file "{0}" was created and it may not get \ cleaned up properly. - +get-field: Error while getting value of field {1} from instance {0} by reflection. +get-method: Error while getting value by getter method {1} on instance {0} by reflection. +set-field: Error while setting value {2} of {3} on field {1} of instance {0} by reflection. +set-method: Error while setting value {2} of {3} by setter method {1} of instance {0} by reflection. Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheBehavesIdentical.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheBehavesIdentical.java?rev=832874&r1=832873&r2=832874&view=diff ============================================================================== --- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheBehavesIdentical.java (original) +++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/datacache/TestDataCacheBehavesIdentical.java Wed Nov 4 21:18:38 2009 @@ -56,9 +56,8 @@ private static final boolean DIRTY = true; private static final boolean REFRESH_FROM_DATACACHE = true; private static final LockModeType NOLOCK = null; - private static final Class ENTITY_NOT_FOUND_ERROR = - EntityNotFoundException.class; - private static final Class NO_ERROR = null; + private static final Class<?> ENTITY_NOT_FOUND_ERROR = EntityNotFoundException.class; + private static final Class<?> NO_ERROR = null; private static final String MARKER_DATACACHE = "in DataCache"; private static final String MARKER_DATABASE = "in Database"; @@ -376,7 +375,7 @@ public void testDirtyRefreshWithNoLockHitsDatabase() { verifyRefresh(WITH_DATACACHE, NOLOCK, DIRTY, !REFRESH_FROM_DATACACHE, - MARKER_DATACACHE); + MARKER_DATABASE); } public void testDirtyRefreshWithNoLockHitsDataCache() { @@ -464,7 +463,7 @@ * @param lock */ public void verifyDeleteDetectionOnRefresh(boolean useDataCache, - boolean dirty, LockModeType lock, Class expectedExceptionType) { + boolean dirty, LockModeType lock, Class<?> expectedExceptionType) { OpenJPAEntityManagerFactorySPI emf = (useDataCache) ? emfWithDataCache : emfWithoutDataCache; @@ -522,49 +521,36 @@ } } - public void testDeleteIsNotDetectedOnCleanRefreshWithoutLockWithDataCache() - { - verifyDeleteDetectionOnRefresh(WITH_DATACACHE, !DIRTY, NOLOCK, - NO_ERROR); + public void testDeleteIsNotDetectedOnCleanRefreshWithoutLockWithDataCache() { + verifyDeleteDetectionOnRefresh(WITH_DATACACHE, !DIRTY, NOLOCK, NO_ERROR); } public void testDeleteIsDetectedOnCleanRefreshWithLockWithDataCache() { - verifyDeleteDetectionOnRefresh(WITH_DATACACHE, !DIRTY, - LockModeType.READ, ENTITY_NOT_FOUND_ERROR); - verifyDeleteDetectionOnRefresh(WITH_DATACACHE, !DIRTY, - LockModeType.WRITE, ENTITY_NOT_FOUND_ERROR); + verifyDeleteDetectionOnRefresh(WITH_DATACACHE, !DIRTY, LockModeType.READ, ENTITY_NOT_FOUND_ERROR); + verifyDeleteDetectionOnRefresh(WITH_DATACACHE, !DIRTY, LockModeType.WRITE, ENTITY_NOT_FOUND_ERROR); } - public void testDeleteIsNotDetectedOnDirtyRefreshWithoutLockWithDataCache() - { - verifyDeleteDetectionOnRefresh(WITH_DATACACHE, DIRTY, NOLOCK, NO_ERROR); + public void testDeleteIsDetectedOnDirtyRefreshWithoutLockWithDataCache() { + verifyDeleteDetectionOnRefresh(WITH_DATACACHE, DIRTY, NOLOCK, ENTITY_NOT_FOUND_ERROR); } public void testDeleteIsDetectedOnDirtyRefreshWithLockWithDataCache() { - verifyDeleteDetectionOnRefresh(WITH_DATACACHE, DIRTY, LockModeType.READ, - ENTITY_NOT_FOUND_ERROR); - verifyDeleteDetectionOnRefresh(WITH_DATACACHE, DIRTY, - LockModeType.WRITE, ENTITY_NOT_FOUND_ERROR); + verifyDeleteDetectionOnRefresh(WITH_DATACACHE, DIRTY, LockModeType.READ, ENTITY_NOT_FOUND_ERROR); + verifyDeleteDetectionOnRefresh(WITH_DATACACHE, DIRTY, LockModeType.WRITE, ENTITY_NOT_FOUND_ERROR); } public void testDeleteIsDetectedOnDirtyRefreshWitDataCache() { - verifyDeleteDetectionOnRefresh(WITH_DATACACHE, DIRTY, LockModeType.READ, - ENTITY_NOT_FOUND_ERROR); - verifyDeleteDetectionOnRefresh(WITH_DATACACHE, DIRTY, - LockModeType.WRITE, ENTITY_NOT_FOUND_ERROR); + verifyDeleteDetectionOnRefresh(WITH_DATACACHE, DIRTY, LockModeType.READ, ENTITY_NOT_FOUND_ERROR); + verifyDeleteDetectionOnRefresh(WITH_DATACACHE, DIRTY, LockModeType.WRITE, ENTITY_NOT_FOUND_ERROR); } - public void testDeleteIsDetectedOnCleanRefreshWithoutLockWithoutDataCache() - { - verifyDeleteDetectionOnRefresh(!WITH_DATACACHE, !DIRTY, NOLOCK, - ENTITY_NOT_FOUND_ERROR); + public void testDeleteIsDetectedOnCleanRefreshWithoutLockWithoutDataCache() { + verifyDeleteDetectionOnRefresh(!WITH_DATACACHE, !DIRTY, NOLOCK, ENTITY_NOT_FOUND_ERROR); } public void testDeleteIsDetectedOnCleanRefreshWithLockWithoutDataCache() { - verifyDeleteDetectionOnRefresh(!WITH_DATACACHE, - !DIRTY, LockModeType.READ, ENTITY_NOT_FOUND_ERROR); - verifyDeleteDetectionOnRefresh(!WITH_DATACACHE, - !DIRTY, LockModeType.WRITE, ENTITY_NOT_FOUND_ERROR); + verifyDeleteDetectionOnRefresh(!WITH_DATACACHE, !DIRTY, LockModeType.READ, ENTITY_NOT_FOUND_ERROR); + verifyDeleteDetectionOnRefresh(!WITH_DATACACHE, !DIRTY, LockModeType.WRITE, ENTITY_NOT_FOUND_ERROR); } } Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/TestRefresh.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/TestRefresh.java?rev=832874&r1=832873&r2=832874&view=diff ============================================================================== --- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/TestRefresh.java (original) +++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/simple/TestRefresh.java Wed Nov 4 21:18:38 2009 @@ -18,12 +18,26 @@ */ package org.apache.openjpa.persistence.simple; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.Map; + +import javax.persistence.CacheRetrieveMode; +import javax.persistence.CacheStoreMode; +import javax.persistence.EntityManager; + +import org.apache.openjpa.kernel.Broker; +import org.apache.openjpa.persistence.JPAProperties; +import org.apache.openjpa.persistence.OpenJPAEntityManager; import org.apache.openjpa.persistence.test.SingleEMTestCase; public class TestRefresh extends SingleEMTestCase { public void setUp() { - super.setUp(CLEAR_TABLES, Item.class, "openjpa.AutoDetach", "commit"); + super.setUp(CLEAR_TABLES, Item.class, + "openjpa.AutoDetach", "commit", + "openjpa.DataCache", "true", + "openjpa.RemoteCommitProvider", "sjvm"); } public void testFlushRefreshNewInstance() { @@ -36,4 +50,79 @@ em.getTransaction().commit(); assertEquals("Test Data", item.getItemData()); } + + /** + * Refresh always bypass L2 cache. + * According to JPA 2.0 Spec Section 3.7.2: + * "The retrieveMode property is ignored for the refresh method, + * which always causes data to be retrieved from the database, not the cache." + */ + public void testRefreshBypassL2Cache() { + String original = "Original L2 Cached Data"; + String sneakUpdate = "Sneak Update"; + em.getTransaction().begin(); + Item item = new Item(); + item.setItemData(original); + em.persist(item); + em.getTransaction().commit(); + assertCached(Item.class, item.getItemId()); + + // Sneakily update with SQL + String sql = "UPDATE I_ITEM SET I_DATA=?1 WHERE I_ID=?2"; + em.getTransaction().begin(); + int updateCount = em.createNativeQuery(sql) + .setParameter(1, sneakUpdate) + .setParameter(2, item.getItemId()) + .executeUpdate(); + assertEquals(1, updateCount); + em.getTransaction().commit(); + + em.getTransaction().begin(); + // Find will find the L2 cached data + item = em.find(Item.class, item.getItemId()); + assertEquals(original, item.getItemData()); + // But refresh will get the actual database record + em.refresh(item); + assertEquals(sneakUpdate, item.getItemData()); + + // Even if cache retrieve mode is set to USE + em.setProperty(JPAProperties.CACHE_RETRIEVE_MODE, CacheRetrieveMode.USE); + em.refresh(item); + assertEquals(sneakUpdate, item.getItemData()); + em.getTransaction().rollback(); + } + + public void testCacheRetrieveModeSetting() { + OpenJPAEntityManager em = emf.createEntityManager(); + em.setProperty(JPAProperties.CACHE_RETRIEVE_MODE, CacheRetrieveMode.USE); + Map<String, Object> properties = em.getProperties(); + if (!properties.containsKey(JPAProperties.CACHE_RETRIEVE_MODE)) { + System.err.println(properties); + fail("Expected " + JPAProperties.CACHE_RETRIEVE_MODE + " properties be returned"); + } + Object mode = properties.get(JPAProperties.CACHE_RETRIEVE_MODE); + assertEquals(mode, CacheRetrieveMode.USE); + } + + public void testCacheStoreModeSetting() { + OpenJPAEntityManager em = emf.createEntityManager(); + em.setProperty(JPAProperties.CACHE_STORE_MODE, CacheStoreMode.USE); + Map<String, Object> properties = em.getProperties(); + if (!properties.containsKey(JPAProperties.CACHE_STORE_MODE)) { + System.err.println(properties); + fail("Expected " + JPAProperties.CACHE_STORE_MODE + " properties be returned"); + } + Object mode = properties.get(JPAProperties.CACHE_STORE_MODE); + assertEquals(mode, CacheStoreMode.USE); + } + + + void assertCached(Class<?> cls, Object oid) { + assertTrue(cls + ":" + oid + " should be in L2 cache, but not", emf.getCache().contains(cls, oid)); + } + + void assertNotCached(Class<?> cls, Object oid) { + assertTrue(cls + ":" + oid + " should not be in L2 cache, but is", !emf.getCache().contains(cls, oid)); + } + } Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java?rev=832874&r1=832873&r2=832874&view=diff ============================================================================== --- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java (original) +++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java Wed Nov 4 21:18:38 2009 @@ -33,6 +33,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.EnumSet; +import java.util.HashMap; import java.util.IdentityHashMap; import java.util.Map; import java.util.Set; @@ -49,6 +50,7 @@ import javax.persistence.metamodel.Metamodel; import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.LogFactory; import org.apache.openjpa.conf.Compatibility; import org.apache.openjpa.conf.OpenJPAConfiguration; import org.apache.openjpa.ee.ManagedRuntime; @@ -105,11 +107,7 @@ private DelegatingBroker _broker; private EntityManagerFactoryImpl _emf; private Map<FetchConfiguration,FetchPlan> _plans = new IdentityHashMap<FetchConfiguration,FetchPlan>(1); - private RuntimeExceptionTranslator _ret = PersistenceExceptions.getRollbackTranslator(this); - - protected final String RETRIEVE_MODE_PROP = "javax.persistence.cache.retrieveMode"; - protected final String STORE_MODE_PROP = "javax.persistence.cache.storeMode"; public EntityManagerImpl() { // for Externalizable @@ -732,10 +730,7 @@ } public void refresh(Object entity) { - assertNotCloseInvoked(); - assertValidAttchedEntity(entity); - _broker.assertWriteOperation(); - _broker.refresh(entity, this); + refresh(entity, null, null); } public void refresh(Object entity, LockModeType mode) { @@ -748,11 +743,19 @@ public void refresh(Object entity, LockModeType mode, Map<String, Object> properties) { assertNotCloseInvoked(); - assertValidAttchedEntity(entity); + assertValidAttchedEntity("refresh", entity); _broker.assertWriteOperation(); - configureCurrentFetchPlan(pushFetchPlan(), properties, mode, true); + DataCacheRetrieveMode rmode = getFetchPlan().getCacheRetrieveMode(); + if (DataCacheRetrieveMode.USE.equals(rmode) || rmode == null) { + getFetchPlan().setCacheRetrieveMode(DataCacheRetrieveMode.BYPASS); + if (rmode != null) { + Log log = _broker.getConfiguration().getConfigurationLog(); + log.warn(_loc.get("cache-retrieve-override", Exceptions.toString(entity))); + } + + } try { _broker.refresh(entity, this); } finally { @@ -1121,7 +1124,7 @@ public LockModeType getLockMode(Object entity) { assertNotCloseInvoked(); _broker.assertActiveTransaction(); - assertValidAttchedEntity(entity); + assertValidAttchedEntity("getLockMode", entity); return MixedLockLevelsHelper.fromLockLevel( _broker.getLockLevel(entity)); } @@ -1132,13 +1135,13 @@ public void lock(Object entity) { assertNotCloseInvoked(); - assertValidAttchedEntity(entity); + assertValidAttchedEntity("lock", entity); _broker.lock(entity, this); } public void lock(Object entity, LockModeType mode, int timeout) { assertNotCloseInvoked(); - assertValidAttchedEntity(entity); + assertValidAttchedEntity("lock", entity); configureCurrentFetchPlan(pushFetchPlan(), null, mode, false); try { @@ -1150,7 +1153,7 @@ public void lock(Object entity, LockModeType mode, Map<String, Object> properties) { assertNotCloseInvoked(); - assertValidAttchedEntity(entity); + assertValidAttchedEntity("lock", entity); _broker.assertActiveTransaction(); configureCurrentFetchPlan(pushFetchPlan(), properties, mode, false); @@ -1315,11 +1318,11 @@ * Throw IllegalArgumentExceptionif if entity is not a valid entity or * if it is detached. */ - void assertValidAttchedEntity(Object entity) { + void assertValidAttchedEntity(String call, Object entity) { OpenJPAStateManager sm = _broker.getStateManager(entity); if (sm == null || !sm.isPersistent() || sm.isDetached()) { - throw new IllegalArgumentException(_loc.get( - "invalid_entity_argument").getMessage()); + throw new IllegalArgumentException(_loc.get("invalid_entity_argument", + call, entity == null ? "null" : Exceptions.toString(entity)).getMessage()); } } @@ -1556,12 +1559,36 @@ return createQuery(jpql); } + /** + * Get the properties used currently by this entity manager. + * The property keys and their values are harvested from kernel artifacts namely + * the Broker and FetchPlan by reflection. + * These property keys and values that denote the bean properties/values of the kernel artifacts + * are converted to the original keys/values that user used to set the properties. + * + */ public Map<String, Object> getProperties() { - Map props = _broker.getProperties(); + Map<String,Object> props = _broker.getProperties(); for (String s : _broker.getSupportedProperties()) { - Method getter = Reflection.findGetter(this.getClass(), getBeanPropertyName(s), false); - if (getter != null) - props.put(s, Reflection.get(this, getter)); + String kernelKey = getBeanPropertyName(s); + Method getter = Reflection.findGetter(this.getClass(), kernelKey, false); + if (getter != null) { + String userKey = JPAProperties.getUserName(kernelKey); + Object kvalue = Reflection.get(this, getter); + props.put(userKey.equals(kernelKey) ? s : userKey, JPAProperties.convertToUserValue(userKey, kvalue)); + } + } + FetchPlan fetch = getFetchPlan(); + Class<?> fetchType = fetch.getClass(); + Set<String> fProperties = Reflection.getBeanStylePropertyNames(fetchType); + for (String s : fProperties) { + String kernelKey = getBeanPropertyName(s); + Method getter = Reflection.findGetter(fetchType, kernelKey, false); + if (getter != null) { + String userKey = JPAProperties.getUserName(kernelKey); + Object kvalue = Reflection.get(fetch, getter); + props.put(userKey.equals(kernelKey) ? s : userKey, JPAProperties.convertToUserValue(userKey, kvalue)); + } } return props; } @@ -1621,17 +1648,17 @@ private void configureCurrentCacheModes(FetchPlan fetch, Map<String, Object> properties) { if (properties == null) return; - CacheRetrieveMode rMode = JPAProperties.get(CacheRetrieveMode.class, JPAProperties.CACHE_RETRIEVE_MODE, - properties); + CacheRetrieveMode rMode = JPAProperties.getEnumValue(CacheRetrieveMode.class, + JPAProperties.CACHE_RETRIEVE_MODE, properties); if (rMode != null) { - fetch.setCacheRetrieveMode(JPAProperties.convertValue(DataCacheRetrieveMode.class, + fetch.setCacheRetrieveMode(JPAProperties.convertToKenelValue(DataCacheRetrieveMode.class, JPAProperties.CACHE_RETRIEVE_MODE, rMode)); properties.remove(JPAProperties.CACHE_RETRIEVE_MODE); } - CacheStoreMode sMode = JPAProperties.get(CacheStoreMode.class, JPAProperties.CACHE_STORE_MODE, - properties); + CacheStoreMode sMode = JPAProperties.getEnumValue(CacheStoreMode.class, + JPAProperties.CACHE_STORE_MODE, properties); if (sMode != null) { - fetch.setCacheStoreMode(JPAProperties.convertValue(DataCacheStoreMode.class, + fetch.setCacheStoreMode(JPAProperties.convertToKenelValue(DataCacheStoreMode.class, JPAProperties.CACHE_STORE_MODE, sMode)); properties.remove(JPAProperties.CACHE_STORE_MODE); } @@ -1670,6 +1697,7 @@ */ private boolean setKernelProperty(Object target, String original, Object value) { String beanProp = getBeanPropertyName(original); + JPAProperties.record(beanProp, original); Class<?> kType = null; Object kValue = null; Method setter = Reflection.findSetter(target.getClass(), beanProp, false); @@ -1694,20 +1722,25 @@ * Extract a bean-style property name from the given string. * If the given string is <code>"a.b.xyz"</code> then returns <code>"xyz"</code> */ - String getBeanPropertyName(String s) { - if (JPAProperties.isValidKey(s)) { - return JPAProperties.getBeanProperty(s); + String getBeanPropertyName(String user) { + String result = user; + if (JPAProperties.isValidKey(user)) { + result = JPAProperties.getBeanProperty(user); + } else { + int dot = user.lastIndexOf('.'); + if (dot != -1) + result = user.substring(dot+1); } - int dot = s.lastIndexOf('.'); - return dot == -1 ? s : s.substring(dot+1); + return result; } + /** * Convert the given value to a value consumable by OpenJPA kernel constructs. */ Object convertUserValue(String key, Object value, Class<?> targetType) { if (JPAProperties.isValidKey(key)) - return JPAProperties.convertValue(targetType, key, value); + return JPAProperties.convertToKenelValue(targetType, key, value); if (value instanceof String) { if ("null".equals(value)) { return null; Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/JPAProperties.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/JPAProperties.java?rev=832874&r1=832873&r2=832874&view=diff ============================================================================== --- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/JPAProperties.java (original) +++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/JPAProperties.java Wed Nov 4 21:18:38 2009 @@ -18,6 +18,7 @@ */ package org.apache.openjpa.persistence; +import java.util.HashMap; import java.util.Map; import javax.persistence.CacheRetrieveMode; @@ -68,13 +69,29 @@ public static final String VALIDATE_PRE_PERSIST = PREFIX + "validation.group.pre-persist"; public static final String VALIDATE_PRE_REMOVE = PREFIX + "validation.group.pre-remove"; public static final String VALIDATE_PRE_UPDATE = PREFIX + "validation.group.pre-update"; - public static final String VALIDATE_GROUP_DEFAULT = "javax.validation.groups.Default"; + private static Map<String,String> _names = new HashMap<String, String>(); + + /** + * Record the given kernel property key (which is a bean property name without any suffix) + * corresponding to the given original JPA/OpenJPA property used by the user to set the values. + */ + static void record(String kernel, String user) { + _names.put(kernel, user); + } + + /** + * Gets the original JPA Property name corresponding to the kernel property key + * (which is a bean property name without any suffix). + */ + static String getUserName(String beanProperty) { + return _names.containsKey(beanProperty) ? _names.get(beanProperty) : beanProperty; + } + /** * Is the given key appears to be a valid JPA specification defined key? * - * @param key * @return true if the given string merely prefixed with <code>javax.persistence.</code>. * Does not really check all the keys defined in the specification. */ @@ -101,16 +118,12 @@ return buf.toString(); } - static <E extends Enum<E>> E get(Class<E> type, String key, Map<String,Object> prop) { - return getEnumValue(type, null, key, prop); - } - /** * Convert the given user value to a value consumable by OpenJPA kernel constructs. * * @return the same value if the given key is not a valid JPA property key or the value is null. */ - public static <T> T convertValue(Class<T> resultType, String key, Object value) { + public static <T> T convertToKenelValue(Class<T> resultType, String key, Object value) { if (value == null) return null; if (JPAProperties.isValidKey(key)) { @@ -124,7 +137,29 @@ return (T)value; } + /** + * Convert the given kernel value to a value visible to the user. + * + * @return the same value if the given key is not a valid JPA property key or the value is null. + */ + public static Object convertToUserValue(String key, Object value) { + if (value == null) + return null; + if (JPAProperties.isValidKey(key)) { + // works because enum values are identical String + if (value instanceof DataCacheRetrieveMode) { + return CacheRetrieveMode.valueOf(value.toString()); + } else if (value instanceof DataCacheStoreMode) { + return CacheStoreMode.valueOf(value.toString()); + } + } + return value; + } + /** + * Get the value of the given key from the given properties after converting it to the given + * enumerated value. + */ public static <E extends Enum<E>> E getEnumValue(Class<E> type, String key, Map<String,Object> prop) { return getEnumValue(type, null, key, prop); } @@ -140,14 +175,28 @@ public static <E extends Enum<E>> E getEnumValue(Class<E> type, E[] values, String key, Map<String,Object> prop) { if (prop == null) return null; - return getEnumValue(type, values, key, prop.get(key)); + return getEnumValue(type, values, prop.get(key)); } - public static <E extends Enum<E>> E getEnumValue(Class<E> type, String key, Object val) { - return getEnumValue(type, null, key, val); + /** + * Gets a enum value of the given type from the given value. + * Converts the original value from a String, if necessary. + * + * @return null if the key does not exist in the given properties. + */ + public static <E extends Enum<E>> E getEnumValue(Class<E> type, Object val) { + return getEnumValue(type, null, val); } - public static <E extends Enum<E>> E getEnumValue(Class<E> type, E[] values, String key, Object val) { + /** + * Gets a enum value of the given type from the given value. + * Converts the original value from a String or ordinal number, if necessary. + * Conversion from an integral number to enum value is only attempted if the allowed enum values + * are provided as non-null, non-empty array. + * + * @return null if the key does not exist in the given properties. + */ + public static <E extends Enum<E>> E getEnumValue(Class<E> type, E[] values, Object val) { if (val == null) return null; if (type.isInstance(val)) Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java?rev=832874&r1=832873&r2=832874&view=diff ============================================================================== --- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java (original) +++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java Wed Nov 4 21:18:38 2009 @@ -525,8 +525,7 @@ /** * Return whether the given persistence unit uses an OpenJPA provider. */ - private static boolean isOpenJPAPersistenceProvider - (PersistenceUnitInfo pinfo, ClassLoader loader) { + private static boolean isOpenJPAPersistenceProvider(PersistenceUnitInfo pinfo, ClassLoader loader) { String provider = pinfo.getPersistenceProviderClassName(); if (StringUtils.isEmpty(provider) || PersistenceProviderImpl.class.getName().equals(provider)) return true; @@ -742,11 +741,7 @@ // startPersistenceUnit() // case 'property' for 'properties' is handled in startElement() case 'c': // class - if ("class".equals(name)) - _info.addManagedClassName(currentText()); - else // FIXME - caching - throw new javax.persistence.PersistenceException( - "Not implemented yet"); + _info.addManagedClassName(currentText()); break; case 'e': // exclude-unlisted-classes setExcludeUnlistedClasses(currentText()); @@ -754,8 +749,7 @@ case 'j': if ("jta-data-source".equals(name)) _info.setJtaDataSourceName(currentText()); - else // jar-file - { + else { // jar-file try { _info.addJarFileName(currentText()); } catch (IllegalArgumentException iae) { @@ -774,12 +768,10 @@ _info.setPersistenceProviderClassName(currentText()); break; case 's' : // shared-cache-mode - _info.setSharedCacheMode(JPAProperties.getEnumValue(SharedCacheMode.class, - JPAProperties.CACHE_MODE, currentText())); + _info.setSharedCacheMode(JPAProperties.getEnumValue(SharedCacheMode.class, currentText())); break; case 'v': // validation-mode - _info.setValidationMode(JPAProperties.getEnumValue(ValidationMode.class, - JPAProperties.VALIDATE_MODE, currentText())); + _info.setValidationMode(JPAProperties.getEnumValue(ValidationMode.class, currentText())); break; } } Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceUnitInfoImpl.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceUnitInfoImpl.java?rev=832874&r1=832873&r2=832874&view=diff ============================================================================== --- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceUnitInfoImpl.java (original) +++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceUnitInfoImpl.java Wed Nov 4 21:18:38 2009 @@ -307,8 +307,7 @@ if (JPAProperties.PROVIDER.equals(key)) setPersistenceProviderClassName((String) val); else if (JPAProperties.TRANSACTION_TYPE.equals(key)) { - setTransactionType(JPAProperties.getEnumValue(PersistenceUnitTransactionType.class, - JPAProperties.TRANSACTION_TYPE, key)); + setTransactionType(JPAProperties.getEnumValue(PersistenceUnitTransactionType.class, key)); } else if (JPAProperties.DATASOURCE_JTA.equals(key)) { if (val instanceof String) { setJtaDataSourceName((String) val); @@ -322,9 +321,9 @@ setNonJtaDataSource((DataSource) val); } } else if (JPAProperties.VALIDATE_MODE.equals(key)) { - setValidationMode(JPAProperties.getEnumValue(ValidationMode.class, JPAProperties.VALIDATE_MODE, val)); + setValidationMode(JPAProperties.getEnumValue(ValidationMode.class, val)); } else if (JPAProperties.CACHE_MODE.equals(key)) { - setSharedCacheMode(JPAProperties.getEnumValue(SharedCacheMode.class, JPAProperties.CACHE_MODE, val)); + setSharedCacheMode(JPAProperties.getEnumValue(SharedCacheMode.class, val)); } else { _props.put(key, val); } Modified: openjpa/trunk/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties?rev=832874&r1=832873&r2=832874&view=diff ============================================================================== --- openjpa/trunk/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties (original) +++ openjpa/trunk/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties Wed Nov 4 21:18:38 2009 @@ -173,8 +173,8 @@ non-unique-result: Query "{0}" selected {1} results, but expected unique result. unwrap-em-invalid: EntityManager can not be unwrapped to an instance of "{0}". unwrap-query-invalid: Query can not be unwrapped to an instance of "{0}". -invalid_entity_argument: Object being locked must be an valid and not detached \ - entity. +invalid_entity_argument: {0} can not be invoked on "{1}". This entity is either \ + detached or not persistent or null. dup-pu: The persistence unit "{0}" was found multiple times in the following \ resources "{1}", but persistence unit names should be unique. The first \ persistence unit matching the provided name in "{2}" is being used. @@ -223,3 +223,4 @@ create-emf-error: Failed to create a provider for "{0}". invalid-version-attribute: Persistence version attribute value "{0}" is not valid. Using version "{1}" by default. not-jpql-or-criteria-query: Query is neither a JPQL SELECT nor a Criteria API query. +cache-retrieve-override: The setting of CacheRetrieveMode.USE is ignored and set to BYPASS for refresh operation. \ No newline at end of file Pinaki
|
||||||||||||||||
| Free Embeddable Forum Powered by Nabble | Help |