use of org.datanucleus.cache.CachedPC in project tests by datanucleus.
the class CacheTest method testRelationshipCachingWhenNontransactional.
public void testRelationshipCachingWhenNontransactional() throws Exception {
try {
PersistenceManager pm = pmf.getPersistenceManager();
Transaction tx = pm.currentTransaction();
// Create sample data
Object acctId = null;
try {
tx.begin();
LoginAccount acct = new LoginAccount("Barney", "Rubble", "brubble", "bambam");
pm.makePersistent(acct);
acctId = JDOHelper.getObjectId(acct);
tx.commit();
} catch (Exception e) {
LOG.error(e);
fail("Exception thrown while creating 1-1 unidirectional relationship data : " + e.getMessage());
} finally {
if (tx.isActive()) {
tx.rollback();
}
pm.close();
}
// Make sure the object isn't in the cache following persistence
pmf.getDataStoreCache().evictAll();
pmf.getDataStoreCache().pinAll(true, LoginAccount.class);
pmf.getDataStoreCache().pinAll(true, Login.class);
// Retrieve the record and check the data
pm = pmf.getPersistenceManager();
try {
LOG.info(">> CacheTest fetching LoginAccount(1)");
LoginAccount acct = (LoginAccount) pm.getObjectById(acctId);
assertTrue("LoginAccount \"firstName\" is incorrect", acct.getFirstName().equals("Barney"));
assertTrue("LoginAccount \"lastName\" is incorrect", acct.getLastName().equals("Rubble"));
LOG.info(">> CacheTest fetching Login(1)");
// Access the login field to make sure it is read. Should get L2 cached now
Login login = acct.getLogin();
assertEquals("Login \"login\" is incorrect", login.getUserName(), "brubble");
assertEquals("Login \"password\" is incorrect", login.getPassword(), "bambam");
} catch (Exception e) {
LOG.error(e);
fail("Exception thrown while interrogating 1-1 unidirectional relationship data : " + e.getMessage());
} finally {
pm.close();
}
// login account is in the cache now after the last getObjectById
LOG.info(">> CacheTest fetching LoginAccount(non-tx)");
CachedPC cpc = ((JDOPersistenceManagerFactory) pmf).getNucleusContext().getLevel2Cache().get(acctId);
assertTrue("LoginAccount is not cached", cpc != null);
assertTrue("LoginAccount \"login\" is not cached", cpc.getFieldValue(2) != null);
// Retrieve the record and check the data
pm = pmf.getPersistenceManager();
try {
LoginAccount acct = (LoginAccount) pm.getObjectById(acctId);
String[] loadedFields = NucleusJDOHelper.getLoadedFields(acct, pm);
LOG.info(">> loadedFields=" + StringUtils.objectArrayToString(loadedFields));
LOG.info(">> Accessing field login");
Login login = acct.getLogin();
LOG.info(">> login=" + login);
} finally {
pm.close();
}
} finally {
clean(LoginAccount.class);
}
}
use of org.datanucleus.cache.CachedPC in project datanucleus-core by datanucleus.
the class StateManagerImpl method updateLevel2CacheForFields.
/**
* Convenience method to update a Level2 cached version of this object if cacheable
* and has not been modified during this transaction.
* @param fieldNumbers Numbers of fields to update in L2 cached object
*/
protected void updateLevel2CacheForFields(int[] fieldNumbers) {
String updateMode = (String) myEC.getProperty(PropertyNames.PROPERTY_CACHE_L2_UPDATE_MODE);
if (updateMode != null && updateMode.equalsIgnoreCase("commit-only")) {
return;
}
if (fieldNumbers == null || fieldNumbers.length == 0) {
return;
}
Level2Cache l2cache = myEC.getNucleusContext().getLevel2Cache();
if (l2cache != null && myEC.getNucleusContext().isClassCacheable(cmd) && !myEC.isObjectModifiedInTransaction(myID)) {
CachedPC<Persistable> cachedPC = l2cache.get(myID);
if (cachedPC != null) {
// This originally just updated the L2 cache for fields where the L2 cache didn't have a value for that field, like this
/*
int[] cacheFieldsToLoad = ClassUtils.getFlagsSetTo(cachedPC.getLoadedFields(), fieldNumbers, false);
if (cacheFieldsToLoad == null || cacheFieldsToLoad.length == 0)
{
return;
}
*/
int[] cacheFieldsToLoad = fieldNumbers;
CachedPC copyCachedPC = cachedPC.getCopy();
if (NucleusLogger.CACHE.isDebugEnabled()) {
NucleusLogger.CACHE.debug(Localiser.msg("026033", StringUtils.toJVMIDString(getObject()), myID, StringUtils.intArrayToString(cacheFieldsToLoad)));
}
provideFields(cacheFieldsToLoad, new L2CachePopulateFieldManager(this, copyCachedPC));
// Replace the current L2 cached object with this one
myEC.getNucleusContext().getLevel2Cache().put(getInternalObjectId(), copyCachedPC);
}
}
}
use of org.datanucleus.cache.CachedPC in project datanucleus-core by datanucleus.
the class ExecutionContextImpl method putObjectsIntoLevel2Cache.
/**
* Method to put the passed objects into the L2 cache.
* Performs the "put" in batches
* @param ops The ObjectProviders whose objects are to be cached
*/
protected void putObjectsIntoLevel2Cache(Set<ObjectProvider> ops) {
int batchSize = nucCtx.getConfiguration().getIntProperty(PropertyNames.PROPERTY_CACHE_L2_BATCHSIZE);
Level2Cache l2Cache = nucCtx.getLevel2Cache();
Map<Object, CachedPC> dataToUpdate = new HashMap<>();
Map<CacheUniqueKey, CachedPC> dataUniqueToUpdate = new HashMap<>();
for (ObjectProvider op : ops) {
Object id = op.getInternalObjectId();
if (id == null || !nucCtx.isClassCacheable(op.getClassMetaData())) {
continue;
}
CachedPC currentCachedPC = l2Cache.get(id);
CachedPC cachedPC = getL2CacheableObject(op, currentCachedPC);
if (cachedPC != null && id != null && !(id instanceof IdentityReference)) {
// Only cache if something to be cached and has identity
dataToUpdate.put(id, cachedPC);
if (dataToUpdate.size() == batchSize) {
// Put this batch of objects in the L2 cache
l2Cache.putAll(dataToUpdate);
dataToUpdate.clear();
}
}
if (op.getClassMetaData().getUniqueMetaData() != null) {
// Check for any unique keys on this object, and cache against the unique key also
List<UniqueMetaData> unimds = op.getClassMetaData().getUniqueMetaData();
if (unimds != null && !unimds.isEmpty()) {
for (UniqueMetaData unimd : unimds) {
CacheUniqueKey uniKey = getCacheUniqueKeyForObjectProvider(op, unimd);
if (uniKey != null) {
dataUniqueToUpdate.put(uniKey, cachedPC);
if (dataUniqueToUpdate.size() == batchSize) {
// Put this batch of unique keyed objects in the L2 cache
l2Cache.putUniqueAll(dataUniqueToUpdate);
dataUniqueToUpdate.clear();
}
}
}
}
}
}
// Put all remaining objects
if (!dataToUpdate.isEmpty()) {
l2Cache.putAll(dataToUpdate);
dataToUpdate.clear();
}
if (!dataUniqueToUpdate.isEmpty()) {
l2Cache.putUniqueAll(dataUniqueToUpdate);
dataUniqueToUpdate.clear();
}
}
Aggregations