/** * Method to check if an element is already persistent, or is managed by a different * ExecutionContext. If not persistent, this will persist it. * * @param ec execution context * @param element The element * @param fieldValues any initial field values to use if persisting the element * @return Whether the element was persisted during this call */ protected boolean validateElementForWriting( ExecutionContext ec, Object element, FieldValues fieldValues) { // TODO Pass in cascade flag and if element not present then throw exception // Check the element type for this collection if (!elementIsPersistentInterface && !validateElementType(ec.getClassLoaderResolver(), element)) { throw new ClassCastException( Localiser.msg( "056033", element.getClass().getName(), ownerMemberMetaData.getFullFieldName(), elementType)); } boolean persisted = false; if (elementsAreEmbedded || elementsAreSerialised) { // Element is embedded/serialised so has no id } else { ObjectProvider elementSM = ec.findObjectProvider(element); if (elementSM != null && elementSM.isEmbedded()) { // Element is already with ObjectProvider and is embedded in another field! throw new NucleusUserException( Localiser.msg("056028", ownerMemberMetaData.getFullFieldName(), element)); } persisted = SCOUtils.validateObjectForWriting(ec, element, fieldValues); } return persisted; }
/** * Method to initialise the SCO from an existing value. * * @param m The object to set from * @param forInsert Whether the object needs inserting in the datastore with this value * @param forUpdate Whether to update the datastore with this value */ public synchronized void initialise(java.util.Map m, boolean forInsert, boolean forUpdate) { if (m != null) { // Check for the case of serialised maps, and assign ObjectProviders to any PC keys/values // without if (SCOUtils.mapHasSerialisedKeysAndValues(ownerMmd) && (ownerMmd.getMap().keyIsPersistent() || ownerMmd.getMap().valueIsPersistent())) { ExecutionContext ec = ownerOP.getExecutionContext(); Iterator iter = m.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = (Map.Entry) iter.next(); Object key = entry.getKey(); Object value = entry.getValue(); if (ownerMmd.getMap().keyIsPersistent()) { ObjectProvider objSM = ec.findObjectProvider(key); if (objSM == null) { objSM = ec.getNucleusContext() .getObjectProviderFactory() .newForEmbedded(ec, key, false, ownerOP, ownerMmd.getAbsoluteFieldNumber()); } } if (ownerMmd.getMap().valueIsPersistent()) { ObjectProvider objSM = ec.findObjectProvider(value); if (objSM == null) { objSM = ec.getNucleusContext() .getObjectProviderFactory() .newForEmbedded(ec, value, false, ownerOP, ownerMmd.getAbsoluteFieldNumber()); } } } } if (backingStore != null && useCache && !isCacheLoaded) { // Mark as loaded isCacheLoaded = true; } if (forInsert) { if (NucleusLogger.PERSISTENCE.isDebugEnabled()) { NucleusLogger.PERSISTENCE.debug( Localiser.msg( "023007", ownerOP.getObjectAsPrintable(), ownerMmd.getName(), "" + m.size())); } makeDirty(); if (useCache) { // Make sure we have all values loaded (e.g if in optimistic tx and we put new entry) loadFromStore(); } if (backingStore != null) { if (SCOUtils.useQueuedUpdate(ownerOP)) { Iterator iter = m.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = (Map.Entry) iter.next(); ownerOP .getExecutionContext() .addOperationToQueue( new MapPutOperation(ownerOP, backingStore, entry.getKey(), entry.getValue())); } } else { backingStore.putAll(ownerOP, m); } } delegate.putAll(m); } else if (forUpdate) { if (NucleusLogger.PERSISTENCE.isDebugEnabled()) { NucleusLogger.PERSISTENCE.debug( Localiser.msg( "023008", ownerOP.getObjectAsPrintable(), ownerMmd.getName(), "" + m.size())); } // TODO This is clear+putAll. Improve it to work out what is changed delegate.clear(); if (backingStore != null) { if (SCOUtils.useQueuedUpdate(ownerOP)) { // If not yet flushed to store then no need to add to queue (since will be handled via // insert) if (ownerOP.isFlushedToDatastore() || !ownerOP.getLifecycleState().isNew()) { ownerOP .getExecutionContext() .addOperationToQueue(new MapClearOperation(ownerOP, backingStore)); } } else { backingStore.clear(ownerOP); } } if (useCache) { // Make sure we have all values loaded (e.g if in optimistic tx and we put new entry) loadFromStore(); } if (backingStore != null) { if (SCOUtils.useQueuedUpdate(ownerOP)) { // If not yet flushed to store then no need to add to queue (since will be handled via // insert) if (ownerOP.isFlushedToDatastore() || !ownerOP.getLifecycleState().isNew()) { Iterator iter = m.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = (Map.Entry) iter.next(); ownerOP .getExecutionContext() .addOperationToQueue( new MapPutOperation( ownerOP, backingStore, entry.getKey(), entry.getValue())); } } } else { backingStore.putAll(ownerOP, m); } } delegate.putAll(m); makeDirty(); } else { if (NucleusLogger.PERSISTENCE.isDebugEnabled()) { NucleusLogger.PERSISTENCE.debug( Localiser.msg( "023007", ownerOP.getObjectAsPrintable(), ownerMmd.getName(), "" + m.size())); } delegate.clear(); delegate.putAll(m); } } }
protected static Object getObjectUsingNondurableIdForResult( final Result result, final AbstractClassMetaData cmd, final ExecutionContext ec, boolean ignoreCache, final int[] fpMembers, String tableName, StoreManager storeMgr, Table table) { if (cmd.hasDiscriminatorStrategy()) { // Check the class for this discriminator value String familyName = HBaseUtils.getFamilyNameForColumn(table.getDiscriminatorColumn()); String columnName = HBaseUtils.getQualifierNameForColumn(table.getDiscriminatorColumn()); Object discValue = new String(result.getValue(familyName.getBytes(), columnName.getBytes())); if (cmd.getDiscriminatorStrategy() == DiscriminatorStrategy.CLASS_NAME && !cmd.getFullClassName().equals(discValue)) { return null; } else if (cmd.getDiscriminatorStrategy() == DiscriminatorStrategy.VALUE_MAP && !cmd.getDiscriminatorValue().equals(discValue)) { return null; } } final FieldManager fm = new FetchFieldManager(ec, cmd, result, table); SCOID id = new SCOID(cmd.getFullClassName()); Object pc = ec.findObject( id, new FieldValues() { // ObjectProvider calls the fetchFields method public void fetchFields(ObjectProvider op) { op.replaceFields(fpMembers, fm); } public void fetchNonLoadedFields(ObjectProvider op) { op.replaceNonLoadedFields(fpMembers, fm); } public FetchPlan getFetchPlanForLoading() { return null; } }, null, ignoreCache, false); if (cmd.isVersioned()) { // Set the version on the object ObjectProvider op = ec.findObjectProvider(pc); Object version = null; VersionMetaData vermd = cmd.getVersionMetaDataForClass(); if (vermd.getFieldName() != null) { // Set the version from the field value AbstractMemberMetaData verMmd = cmd.getMetaDataForMember(vermd.getFieldName()); version = op.provideField(verMmd.getAbsoluteFieldNumber()); } else { // Get the surrogate version from the datastore version = HBaseUtils.getSurrogateVersionForObject(cmd, result, tableName, storeMgr); } op.setVersion(version); } if (result.getRow() != null) { ObjectProvider sm = ec.findObjectProvider(pc); sm.setAssociatedValue("HBASE_ROW_KEY", result.getRow()); } return pc; }
protected static Object getObjectUsingDatastoreIdForResult( final Result result, final AbstractClassMetaData cmd, final ExecutionContext ec, boolean ignoreCache, final int[] fpMembers, String tableName, StoreManager storeMgr, Table table) { if (cmd.hasDiscriminatorStrategy()) { // Check the class for this discriminator value String familyName = HBaseUtils.getFamilyNameForColumn(table.getDiscriminatorColumn()); String columnName = HBaseUtils.getQualifierNameForColumn(table.getDiscriminatorColumn()); Object discValue = new String(result.getValue(familyName.getBytes(), columnName.getBytes())); if (cmd.getDiscriminatorStrategy() == DiscriminatorStrategy.CLASS_NAME && !cmd.getFullClassName().equals(discValue)) { return null; } else if (cmd.getDiscriminatorStrategy() == DiscriminatorStrategy.VALUE_MAP && !cmd.getDiscriminatorValue().equals(discValue)) { return null; } } String dsidFamilyName = HBaseUtils.getFamilyNameForColumn(table.getDatastoreIdColumn()); String dsidColumnName = HBaseUtils.getQualifierNameForColumn(table.getDatastoreIdColumn()); Object id = null; try { byte[] bytes = result.getValue(dsidFamilyName.getBytes(), dsidColumnName.getBytes()); if (bytes != null) { ByteArrayInputStream bis = new ByteArrayInputStream(bytes); ObjectInputStream ois = new ObjectInputStream(bis); Object key = ois.readObject(); id = ec.getNucleusContext().getIdentityManager().getDatastoreId(cmd.getFullClassName(), key); ois.close(); bis.close(); } else { throw new NucleusException( "Retrieved identity for family=" + dsidFamilyName + " column=" + dsidColumnName + " IS NULL"); } } catch (Exception e) { throw new NucleusException(e.getMessage(), e); } final FieldManager fm = new FetchFieldManager(ec, cmd, result, table); Object pc = ec.findObject( id, new FieldValues() { // ObjectProvider calls the fetchFields method public void fetchFields(ObjectProvider op) { op.replaceFields(fpMembers, fm); } public void fetchNonLoadedFields(ObjectProvider op) { op.replaceNonLoadedFields(fpMembers, fm); } public FetchPlan getFetchPlanForLoading() { return null; } }, null, ignoreCache, false); if (cmd.isVersioned()) { // Set the version on the object ObjectProvider op = ec.findObjectProvider(pc); Object version = null; VersionMetaData vermd = cmd.getVersionMetaDataForClass(); if (vermd.getFieldName() != null) { // Set the version from the field value AbstractMemberMetaData verMmd = cmd.getMetaDataForMember(vermd.getFieldName()); version = op.provideField(verMmd.getAbsoluteFieldNumber()); } else { // Get the surrogate version from the datastore version = HBaseUtils.getSurrogateVersionForObject(cmd, result, tableName, storeMgr); } op.setVersion(version); } if (result.getRow() != null) { ObjectProvider sm = ec.findObjectProvider(pc); sm.setAssociatedValue("HBASE_ROW_KEY", result.getRow()); } return pc; }
/** * Method to initialise the SCO from an existing value. * * @param o The object to set from * @param forInsert Whether the object needs inserting in the datastore with this value * @param forUpdate Whether to update the datastore with this value */ public void initialise(Object o, boolean forInsert, boolean forUpdate) { Collection c = (Collection) o; if (c != null) { // Check for the case of serialised PC elements, and assign ObjectProviders to the elements // without if (SCOUtils.collectionHasSerialisedElements(ownerMmd) && ownerMmd.getCollection().elementIsPersistent()) { ExecutionContext ec = ownerOP.getExecutionContext(); Iterator iter = c.iterator(); while (iter.hasNext()) { Object pc = iter.next(); ObjectProvider objSM = ec.findObjectProvider(pc); if (objSM == null) { objSM = ec.newObjectProviderForEmbedded( pc, false, ownerOP, ownerMmd.getAbsoluteFieldNumber()); } } } if (backingStore != null && useCache && !isCacheLoaded) { // Mark as loaded isCacheLoaded = true; } if (forInsert) { if (NucleusLogger.PERSISTENCE.isDebugEnabled()) { NucleusLogger.PERSISTENCE.debug( LOCALISER.msg( "023007", ownerOP.getObjectAsPrintable(), ownerMmd.getName(), "" + c.size())); } if (useCache) { loadFromStore(); } if (ownerOP != null && ownerOP.getExecutionContext().getManageRelations()) { // Relationship management Iterator iter = c.iterator(); RelationshipManager relMgr = ownerOP.getExecutionContext().getRelationshipManager(ownerOP); while (iter.hasNext()) { relMgr.relationAdd(ownerMmd.getAbsoluteFieldNumber(), iter.next()); } } if (backingStore != null) { if (SCOUtils.useQueuedUpdate(queued, ownerOP)) { for (Object element : c) { ownerOP .getExecutionContext() .addOperationToQueue(new CollectionAddOperation(ownerOP, backingStore, element)); } } else { try { backingStore.addAll(ownerOP, c, (useCache ? delegate.size() : -1)); } catch (NucleusDataStoreException dse) { NucleusLogger.PERSISTENCE.warn( LOCALISER.msg("023013", "addAll", ownerMmd.getName(), dse)); } } } delegate.addAll(c); makeDirty(); } else if (forUpdate) { if (NucleusLogger.PERSISTENCE.isDebugEnabled()) { NucleusLogger.PERSISTENCE.debug( LOCALISER.msg( "023008", ownerOP.getObjectAsPrintable(), ownerMmd.getName(), "" + c.size())); } // Detect which objects are added and which are deleted if (useCache) { isCacheLoaded = false; // Mark as false since need to load the old collection loadFromStore(); for (Object elem : c) { if (!delegate.contains(elem)) { add(elem); } } java.util.TreeSet delegateCopy = new java.util.TreeSet(delegate); for (Object elem : delegateCopy) { if (!c.contains(elem)) { remove(elem); } } } else { for (Object elem : c) { if (!contains(elem)) { add(elem); } } Iterator iter = iterator(); while (iter.hasNext()) { Object elem = iter.next(); if (!c.contains(elem)) { remove(elem); } } } } else { if (NucleusLogger.PERSISTENCE.isDebugEnabled()) { NucleusLogger.PERSISTENCE.debug( LOCALISER.msg( "023007", ownerOP.getObjectAsPrintable(), ownerMmd.getName(), "" + c.size())); } delegate.clear(); delegate.addAll(c); } } }
/** * Method to initialise the SCO from an existing value. * * @param c The object to set from * @param forInsert Whether the object needs inserting in the datastore with this value * @param forUpdate Whether to update the SCO in the datastore with this value */ public void initialise(java.util.ArrayList c, boolean forInsert, boolean forUpdate) { if (c != null) { // Check for the case of serialised PC elements, and assign ObjectProviders to the elements // without if (SCOUtils.collectionHasSerialisedElements(ownerMmd) && ownerMmd.getCollection().elementIsPersistent()) { ExecutionContext ec = ownerOP.getExecutionContext(); Iterator iter = c.iterator(); while (iter.hasNext()) { Object pc = iter.next(); ObjectProvider objOP = ec.findObjectProvider(pc); if (objOP == null) { objOP = ec.getNucleusContext() .getObjectProviderFactory() .newForEmbedded(ec, pc, false, ownerOP, ownerMmd.getAbsoluteFieldNumber()); } } } if (backingStore != null && useCache && !isCacheLoaded) { // Mark as loaded so we just use the value isCacheLoaded = true; } if (forInsert) { if (NucleusLogger.PERSISTENCE.isDebugEnabled()) { NucleusLogger.PERSISTENCE.debug( Localiser.msg( "023007", ownerOP.getObjectAsPrintable(), ownerMmd.getName(), "" + c.size())); } if (useCache) { loadFromStore(); } if (backingStore != null) { if (SCOUtils.useQueuedUpdate(queued, ownerOP)) { for (Object element : c) { ownerOP .getExecutionContext() .addOperationToQueue(new CollectionAddOperation(ownerOP, backingStore, element)); } } else { try { backingStore.addAll(ownerOP, c, (useCache ? delegate.size() : -1)); } catch (NucleusDataStoreException dse) { NucleusLogger.PERSISTENCE.warn( Localiser.msg("023013", "addAll", ownerMmd.getName(), dse)); } } } makeDirty(); delegate.addAll(c); } else if (forUpdate) { if (NucleusLogger.PERSISTENCE.isDebugEnabled()) { NucleusLogger.PERSISTENCE.debug( Localiser.msg( "023008", ownerOP.getObjectAsPrintable(), ownerMmd.getName(), "" + c.size())); } // TODO This does clear+addAll : Improve this and work out which elements are added and // which deleted if (backingStore != null) { if (SCOUtils.useQueuedUpdate(queued, ownerOP)) { ownerOP .getExecutionContext() .addOperationToQueue(new CollectionClearOperation(ownerOP, backingStore)); } else { backingStore.clear(ownerOP); } } if (useCache) { loadFromStore(); } if (backingStore != null) { if (SCOUtils.useQueuedUpdate(queued, ownerOP)) { for (Object element : c) { ownerOP .getExecutionContext() .addOperationToQueue(new CollectionAddOperation(ownerOP, backingStore, element)); } } else { try { backingStore.addAll(ownerOP, c, (useCache ? delegate.size() : -1)); } catch (NucleusDataStoreException dse) { NucleusLogger.PERSISTENCE.warn( Localiser.msg("023013", "addAll", ownerMmd.getName(), dse)); } } } delegate.addAll(c); makeDirty(); } else { if (NucleusLogger.PERSISTENCE.isDebugEnabled()) { NucleusLogger.PERSISTENCE.debug( Localiser.msg( "023007", ownerOP.getObjectAsPrintable(), ownerMmd.getName(), "" + c.size())); } delegate.clear(); delegate.addAll(c); } } }