use of org.datanucleus.enhancement.Persistable in project tests by datanucleus.
the class JDOPersistenceTestCase method cleanup.
protected void cleanup(Set<Object> toCleanup) throws Exception {
// Keep track of what is being deleted so we don't need to
// delete what has already been deleted by the cascade.
Set<Object> deleted = new HashSet<>();
DeleteLifecycleListener listener = new DeleteLifecycleListener() {
@Override
public void preDelete(InstanceLifecycleEvent event) {
// Nothing to do
}
@Override
public void postDelete(InstanceLifecycleEvent event) {
Object id = ((Persistable) event.getSource()).dnGetObjectId();
deleted.add(id);
}
};
try (PersistenceManager pm = pmf.getPersistenceManager()) {
pm.addInstanceLifecycleListener(listener, Object.class);
Set<Object> toDelete = toCleanup;
Set<Object> retry = new HashSet<>();
int attempts = 0;
do {
// Try to delete
for (Object id : toDelete) {
try {
if (LOG.isDebugEnabled()) {
LOG.debug("Cleaning up: " + id);
}
if (deleted.contains(id)) {
if (LOG.isDebugEnabled()) {
LOG.debug("Already deleted: " + id);
}
} else {
Object object = pm.getObjectById(id, false);
boolean cleanerRun = false;
for (Entry<String, Consumer<PersistenceManager>> entry : cleanersByPrefix.entrySet()) {
if (object.getClass().getName().startsWith(entry.getKey())) {
entry.getValue().accept(pm);
cleanerRun = true;
break;
}
}
if (!cleanerRun) {
LOG.debug(">> calling deletePersistent on " + StringUtils.toJVMIDString(object) + " state=" + JDOHelper.getObjectState(object));
pm.deletePersistent(object);
}
if (LOG.isDebugEnabled()) {
LOG.debug("Cleaned " + id + " successfully");
}
}
} catch (Exception e) {
LOG.warn("Exception in delete process", e);
if (LOG.isDebugEnabled()) {
LOG.debug("Failed, retrying later: " + id);
}
retry.add(id);
}
}
attempts++;
if (!retry.isEmpty() && attempts > MAX_CLEANUP_ATTEMPTS) {
// Give up
retry.clear();
// throw new Exception("Fail to cleanup the following object(s) after " + attempts + " attempts: " + retry);
}
// Try again
toDelete.clear();
toDelete.addAll(retry);
retry.clear();
} while (!toDelete.isEmpty());
}
}
use of org.datanucleus.enhancement.Persistable in project datanucleus-api-jdo by datanucleus.
the class NucleusJDOHelper method isDirty.
/**
* Accessor for whether the specified member (field/property) of the passed persistable object is dirty.
* @param obj The persistable object
* @param memberName Name of the field/property
* @param pm PersistenceManager (if the object is detached)
* @return Whether the member is dirty
*/
public static Boolean isDirty(Object obj, String memberName, PersistenceManager pm) {
if (obj == null || !(obj instanceof Persistable)) {
return null;
}
Persistable pc = (Persistable) obj;
if (isDetached(pc)) {
// Temporarily attach a StateManager to access the detached field information
ExecutionContext ec = ((JDOPersistenceManager) pm).getExecutionContext();
ObjectProvider op = ec.getNucleusContext().getObjectProviderFactory().newForDetached(ec, pc, getObjectId(pc), null);
pc.dnReplaceStateManager(op);
op.retrieveDetachState(op);
int position = op.getClassMetaData().getAbsolutePositionOfMember(memberName);
boolean[] dirtyFieldNumbers = op.getDirtyFields();
pc.dnReplaceStateManager(null);
return dirtyFieldNumbers[position];
}
ExecutionContext ec = (ExecutionContext) pc.dnGetExecutionContext();
ObjectProvider op = ec.findObjectProvider(pc);
if (op == null) {
return null;
}
int position = op.getClassMetaData().getAbsolutePositionOfMember(memberName);
boolean[] dirtyFieldNumbers = op.getDirtyFields();
return dirtyFieldNumbers[position];
}
use of org.datanucleus.enhancement.Persistable in project datanucleus-api-jdo by datanucleus.
the class NucleusJDOHelper method isLoaded.
/**
* Accessor for whether the specified member (field/property) of the passed persistable object is loaded.
* @param obj The persistable object
* @param memberName Name of the field/property
* @param pm PersistenceManager (if the object is detached)
* @return Whether the member is loaded
*/
public static Boolean isLoaded(Object obj, String memberName, PersistenceManager pm) {
if (obj == null || !(obj instanceof Persistable)) {
return null;
}
Persistable pc = (Persistable) obj;
if (isDetached(pc)) {
// Temporarily attach a StateManager to access the detached field information
ExecutionContext ec = ((JDOPersistenceManager) pm).getExecutionContext();
ObjectProvider op = ec.getNucleusContext().getObjectProviderFactory().newForDetached(ec, pc, getObjectId(pc), null);
pc.dnReplaceStateManager(op);
op.retrieveDetachState(op);
int position = op.getClassMetaData().getAbsolutePositionOfMember(memberName);
boolean loaded = op.isFieldLoaded(position);
pc.dnReplaceStateManager(null);
return loaded;
}
ExecutionContext ec = (ExecutionContext) pc.dnGetExecutionContext();
ObjectProvider op = ec.findObjectProvider(pc);
if (op == null) {
return null;
}
int position = op.getClassMetaData().getAbsolutePositionOfMember(memberName);
return op.isFieldLoaded(position);
}
use of org.datanucleus.enhancement.Persistable in project datanucleus-core by datanucleus.
the class StateManagerImpl method dumpPC.
// ------------------------------ Helper Methods ---------------------------
/**
* Method to dump a persistable object to the specified PrintWriter.
* @param pc The persistable object
* @param out The PrintWriter
*/
private static void dumpPC(Object pc, AbstractClassMetaData cmd, PrintWriter out) {
out.println(StringUtils.toJVMIDString(pc));
if (pc == null) {
return;
}
out.print("dnStateManager = " + peekField(pc, "dnStateManager"));
out.print("dnFlags = ");
Object flagsObj = peekField(pc, "dnFlags");
if (flagsObj instanceof Byte) {
switch(((Byte) flagsObj).byteValue()) {
case Persistable.LOAD_REQUIRED:
out.println("LOAD_REQUIRED");
break;
case Persistable.READ_OK:
out.println("READ_OK");
break;
case Persistable.READ_WRITE_OK:
out.println("READ_WRITE_OK");
break;
default:
out.println("???");
break;
}
} else {
out.println(flagsObj);
}
Class c = pc.getClass();
do {
AbstractMemberMetaData[] mmds = cmd.getManagedMembers();
for (AbstractMemberMetaData mmd : mmds) {
out.println(mmd.getName());
out.println(" = ");
out.println(peekField(pc, mmd.getName()));
}
c = c.getSuperclass();
cmd = cmd.getSuperAbstractClassMetaData();
} while (c != null && Persistable.class.isAssignableFrom(c));
}
use of org.datanucleus.enhancement.Persistable in project datanucleus-core by datanucleus.
the class StateManagerImpl method loadFieldsFromLevel2Cache.
/**
* Convenience method to retrieve field values from an L2 cached object if they are loaded in that object.
* If the object is not in the L2 cache then just returns, and similarly if the required fields aren't available.
* @param fieldNumbers Numbers of fields to load from the L2 cache
* @return The fields that couldn't be loaded
*/
protected int[] loadFieldsFromLevel2Cache(int[] fieldNumbers) {
// Only continue if there are fields, and not being deleted/flushed etc
if (fieldNumbers == null || fieldNumbers.length == 0 || myEC.isFlushing() || myLC.isDeleted() || isDeleting() || getExecutionContext().getTransaction().isCommitting()) {
return fieldNumbers;
}
// TODO Drop this check when we're confident that this doesn't affect some use-cases
if (!myEC.getNucleusContext().getConfiguration().getBooleanProperty(PropertyNames.PROPERTY_CACHE_L2_LOADFIELDS, true)) {
return fieldNumbers;
}
Level2Cache l2cache = myEC.getNucleusContext().getLevel2Cache();
if (l2cache != null && myEC.getNucleusContext().isClassCacheable(cmd)) {
CachedPC<Persistable> cachedPC = l2cache.get(myID);
if (cachedPC != null) {
int[] cacheFieldsToLoad = ClassUtils.getFlagsSetTo(cachedPC.getLoadedFields(), fieldNumbers, true);
if (cacheFieldsToLoad != null && cacheFieldsToLoad.length > 0) {
if (NucleusLogger.CACHE.isDebugEnabled()) {
NucleusLogger.CACHE.debug(Localiser.msg("026034", StringUtils.toJVMIDString(getObject()), myID, StringUtils.intArrayToString(cacheFieldsToLoad)));
}
L2CacheRetrieveFieldManager l2RetFM = new L2CacheRetrieveFieldManager(this, cachedPC);
this.replaceFields(cacheFieldsToLoad, l2RetFM);
int[] fieldsNotLoaded = l2RetFM.getFieldsNotLoaded();
if (fieldsNotLoaded != null) {
for (int i = 0; i < fieldsNotLoaded.length; i++) {
loadedFields[fieldsNotLoaded[i]] = false;
}
}
}
}
}
return ClassUtils.getFlagsSetTo(loadedFields, fieldNumbers, false);
}
Aggregations