use of org.datanucleus.state.DNStateManager in project datanucleus-rdbms by datanucleus.
the class ArrayMapping method postInsert.
// ---------------------- Implementation of MappingCallbacks ----------------------------------
/**
* Method to be called after the insert of the owner class element.
* @param ownerSM StateManager of the owner
*/
public void postInsert(DNStateManager ownerSM) {
ExecutionContext ec = ownerSM.getExecutionContext();
Object value = ownerSM.provideField(getAbsoluteFieldNumber());
if (value == null) {
return;
}
if (containerIsStoredInSingleColumn()) {
if (mmd.getArray().elementIsPersistent()) {
// Make sure all persistable elements have StateManagers
Object[] arrElements = (Object[]) value;
for (Object elem : arrElements) {
if (elem != null) {
DNStateManager elemSM = ec.findStateManager(elem);
if (elemSM == null || ec.getApiAdapter().getExecutionContext(elem) == null) {
elemSM = ec.getNucleusContext().getStateManagerFactory().newForEmbedded(ec, elem, false, ownerSM, mmd.getAbsoluteFieldNumber(), PersistableObjectType.EMBEDDED_ARRAY_ELEMENT_PC);
}
}
}
}
return;
}
int arrayLength = Array.getLength(value);
boolean persistentElements = (mmd.getRelationType(ec.getClassLoaderResolver()) != RelationType.NONE);
boolean needsAttaching = false;
if (persistentElements) {
Object[] array = (Object[]) value;
if (!mmd.isCascadePersist()) {
// Check that all elements are persistent before continuing and throw exception if necessary
if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
NucleusLogger.PERSISTENCE.debug(Localiser.msg("007006", mmd.getFullFieldName()));
}
for (int i = 0; i < arrayLength; i++) {
if (!ec.getApiAdapter().isDetached(array[i]) && !ec.getApiAdapter().isPersistent(array[i])) {
// Element is not persistent so throw exception
throw new ReachableObjectNotCascadedException(mmd.getFullFieldName(), array[i]);
}
}
} else {
// Reachability
if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
NucleusLogger.PERSISTENCE.debug(Localiser.msg("007007", IdentityUtils.getPersistableIdentityForId(ownerSM.getInternalObjectId()), mmd.getFullFieldName()));
}
}
for (int i = 0; i < arrayLength; i++) {
if (ec.getApiAdapter().isDetached(array[i])) {
needsAttaching = true;
break;
}
}
}
if (needsAttaching) {
// Create a wrapper and attach the elements (and add the others)
SCO collWrapper = replaceFieldWithWrapper(ownerSM, null);
if (arrayLength > 0) {
collWrapper.attachCopy(value);
// The attach will have put entries in the operationQueue if using optimistic, so flush them
ec.flushOperationsForBackingStore(((BackedSCO) collWrapper).getBackingStore(), ownerSM);
}
} else {
if (arrayLength > 0) {
// Add the elements direct to the datastore
((ArrayStore) storeMgr.getBackingStoreForField(ec.getClassLoaderResolver(), mmd, null)).set(ownerSM, value);
}
}
}
use of org.datanucleus.state.DNStateManager in project datanucleus-rdbms by datanucleus.
the class PersistentClassROF method findObjectWithIdAndLoadFields.
/**
* Method to lookup an object for an id, and specify its FieldValues using the ResultSet. Works for all identity types.
* @param id The identity (DatastoreId, Application id, or SCOID when nondurable)
* @param membersToLoad Absolute numbers of members to load
* @param membersToStore Absolute numbers of members to store in StateManager (for later)
* @param pcClass The class of the required object if known
* @param cmd Metadata for the type
* @param surrogateVersion The version when the object has a surrogate version field
* @return The persistable object for this id
*/
private T findObjectWithIdAndLoadFields(final Object id, final int[] membersToLoad, final int[] membersToStore, Class pcClass, final AbstractClassMetaData cmd, final Object surrogateVersion) {
return (T) ec.findObject(id, new FieldValues() {
// TODO If we ever support just loading a FK value but not instantiating this needs to store the value in StateManager.
public void fetchFields(DNStateManager sm) {
resultSetGetter.setStateManager(sm);
sm.replaceFields(membersToLoad, resultSetGetter, false);
// Set version
if (surrogateVersion != null) {
// Surrogate version field
sm.setVersion(surrogateVersion);
} else if (cmd.getVersionMetaData() != null && cmd.getVersionMetaData().getMemberName() != null) {
// Version stored in a normal field
VersionMetaData vermd = cmd.getVersionMetaData();
int versionFieldNumber = rootCmd.getMetaDataForMember(vermd.getMemberName()).getAbsoluteFieldNumber();
if (resultMapping.getMappingForMemberPosition(versionFieldNumber) != null) {
Object verFieldValue = sm.provideField(versionFieldNumber);
if (verFieldValue != null) {
sm.setVersion(verFieldValue);
}
}
}
if (membersToStore != null) {
for (int i = 0; i < membersToStore.length; i++) {
StatementMappingIndex mapIdx = mappingDefinition.getMappingForMemberPosition(membersToStore[i]);
JavaTypeMapping m = mapIdx.getMapping();
if (m instanceof PersistableMapping) {
// Create the identity of the related object
AbstractClassMetaData memberCmd = ((PersistableMapping) m).getClassMetaData();
Object memberId = null;
if (memberCmd.getIdentityType() == IdentityType.DATASTORE) {
memberId = MappingHelper.getDatastoreIdentityForResultSetRow(ec, m, rs, mapIdx.getColumnPositions(), memberCmd);
} else if (memberCmd.getIdentityType() == IdentityType.APPLICATION) {
memberId = MappingHelper.getApplicationIdentityForResultSetRow(ec, m, rs, mapIdx.getColumnPositions(), memberCmd);
} else {
break;
}
if (memberId == null) {
// Just set the member to null and don't bother saving the value
sm.replaceField(membersToStore[i], null);
} else {
// Store the "id" value in case the member is ever accessed
sm.storeFieldValue(membersToStore[i], memberId);
}
}
}
}
}
public void fetchNonLoadedFields(DNStateManager sm) {
resultSetGetter.setStateManager(sm);
// TODO Use membersToStore here?
sm.replaceNonLoadedFields(membersToLoad, resultSetGetter);
}
public FetchPlan getFetchPlanForLoading() {
return fp;
}
}, pcClass, ignoreCache, false);
}
use of org.datanucleus.state.DNStateManager in project datanucleus-rdbms by datanucleus.
the class LocateBulkRequest method processResults.
private DNStateManager[] processResults(ResultSet rs, DNStateManager[] sms) throws SQLException {
List<DNStateManager> missingSMs = new ArrayList<>();
for (int i = 0; i < sms.length; i++) {
missingSMs.add(sms[i]);
}
ExecutionContext ec = sms[0].getExecutionContext();
while (rs.next()) {
FieldManager resultFM = new ResultSetGetter(ec, rs, resultMapping, cmd);
Object id = null;
Object key = null;
if (cmd.getIdentityType() == IdentityType.DATASTORE) {
StatementMappingIndex idx = resultMapping.getMappingForMemberPosition(SurrogateColumnType.DATASTORE_ID.getFieldNumber());
JavaTypeMapping idMapping = idx.getMapping();
key = idMapping.getObject(ec, rs, idx.getColumnPositions());
if (IdentityUtils.isDatastoreIdentity(key)) {
// If mapping is OIDMapping then returns an OID rather than the column value
key = IdentityUtils.getTargetKeyForDatastoreIdentity(key);
}
} else if (cmd.getIdentityType() == IdentityType.APPLICATION) {
if (cmd.usesSingleFieldIdentityClass()) {
int[] pkFieldNums = cmd.getPKMemberPositions();
AbstractMemberMetaData pkMmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(pkFieldNums[0]);
if (pkMmd.getType() == int.class) {
key = resultFM.fetchIntField(pkFieldNums[0]);
} else if (pkMmd.getType() == short.class) {
key = resultFM.fetchShortField(pkFieldNums[0]);
} else if (pkMmd.getType() == long.class) {
key = resultFM.fetchLongField(pkFieldNums[0]);
} else if (pkMmd.getType() == char.class) {
key = resultFM.fetchCharField(pkFieldNums[0]);
} else if (pkMmd.getType() == boolean.class) {
key = resultFM.fetchBooleanField(pkFieldNums[0]);
} else if (pkMmd.getType() == byte.class) {
key = resultFM.fetchByteField(pkFieldNums[0]);
} else if (pkMmd.getType() == double.class) {
key = resultFM.fetchDoubleField(pkFieldNums[0]);
} else if (pkMmd.getType() == float.class) {
key = resultFM.fetchFloatField(pkFieldNums[0]);
} else if (pkMmd.getType() == String.class) {
key = resultFM.fetchStringField(pkFieldNums[0]);
} else {
key = resultFM.fetchObjectField(pkFieldNums[0]);
}
} else {
id = IdentityUtils.getApplicationIdentityForResultSetRow(ec, cmd, null, true, resultFM);
}
}
// Find which StateManager this row is for
DNStateManager sm = null;
for (DNStateManager missingSM : missingSMs) {
Object opId = missingSM.getInternalObjectId();
if (cmd.getIdentityType() == IdentityType.DATASTORE) {
Object opKey = IdentityUtils.getTargetKeyForDatastoreIdentity(opId);
if (key != null && opKey.getClass() != key.getClass()) {
opKey = TypeConversionHelper.convertTo(opKey, key.getClass());
}
if (opKey.equals(key)) {
sm = missingSM;
break;
}
} else if (cmd.getIdentityType() == IdentityType.APPLICATION) {
if (cmd.usesSingleFieldIdentityClass()) {
Object opKey = IdentityUtils.getTargetKeyForSingleFieldIdentity(opId);
if (opKey.equals(key)) {
sm = missingSM;
break;
}
} else {
if (opId.equals(id)) {
sm = missingSM;
break;
}
}
}
}
if (sm != null) {
// Mark StateManager as processed
missingSMs.remove(sm);
// Load up any unloaded fields that we have selected
int[] selectedMemberNums = resultMapping.getMemberNumbers();
int[] unloadedMemberNums = ClassUtils.getFlagsSetTo(sm.getLoadedFields(), selectedMemberNums, false);
if (unloadedMemberNums != null && unloadedMemberNums.length > 0) {
sm.replaceFields(unloadedMemberNums, resultFM);
}
// Load version if present and not yet set
JavaTypeMapping versionMapping = table.getSurrogateMapping(SurrogateColumnType.VERSION, false);
if (sm.getTransactionalVersion() == null && versionMapping != null) {
VersionMetaData currentVermd = table.getVersionMetaData();
Object datastoreVersion = null;
if (currentVermd != null) {
if (currentVermd.getMemberName() == null) {
// Surrogate version
// Why use true now?
versionMapping = table.getSurrogateMapping(SurrogateColumnType.VERSION, true);
StatementMappingIndex verIdx = resultMapping.getMappingForMemberPosition(SurrogateColumnType.VERSION.getFieldNumber());
datastoreVersion = versionMapping.getObject(ec, rs, verIdx.getColumnPositions());
} else {
datastoreVersion = sm.provideField(cmd.getAbsolutePositionOfMember(currentVermd.getMemberName()));
}
sm.setVersion(datastoreVersion);
}
}
}
}
if (!missingSMs.isEmpty()) {
return missingSMs.toArray(new DNStateManager[missingSMs.size()]);
}
return null;
}
use of org.datanucleus.state.DNStateManager in project datanucleus-rdbms by datanucleus.
the class LocateBulkRequest method execute.
/**
* Method performing the location of the records in the datastore.
* @param sms StateManagers to be located
* @throws NucleusObjectNotFoundException with nested exceptions for each of missing objects (if any)
*/
public void execute(DNStateManager[] sms) {
if (sms == null || sms.length == 0) {
return;
}
if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
// Debug information about what we are retrieving
StringBuilder str = new StringBuilder();
for (int i = 0; i < sms.length; i++) {
if (i > 0) {
str.append(", ");
}
str.append(sms[i].getInternalObjectId());
}
NucleusLogger.PERSISTENCE.debug(Localiser.msg("052223", str.toString(), table));
}
ExecutionContext ec = sms[0].getExecutionContext();
RDBMSStoreManager storeMgr = table.getStoreManager();
AbstractClassMetaData cmd = sms[0].getClassMetaData();
// Override with pessimistic lock where specified
LockMode lockType = ec.getLockManager().getLockMode(sms[0].getInternalObjectId());
boolean locked = (lockType == LockMode.LOCK_PESSIMISTIC_READ || lockType == LockMode.LOCK_PESSIMISTIC_WRITE) ? true : ec.getSerializeReadForClass(cmd.getFullClassName());
String statement = getStatement(table, sms, locked);
try {
ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
SQLController sqlControl = storeMgr.getSQLController();
try {
PreparedStatement ps = sqlControl.getStatementForQuery(mconn, statement);
try {
// Provide the primary key field(s)
for (int i = 0; i < sms.length; i++) {
if (cmd.getIdentityType() == IdentityType.DATASTORE) {
StatementMappingIndex datastoreIdx = mappingDefinitions[i].getMappingForMemberPosition(SurrogateColumnType.DATASTORE_ID.getFieldNumber());
for (int j = 0; j < datastoreIdx.getNumberOfParameterOccurrences(); j++) {
table.getSurrogateMapping(SurrogateColumnType.DATASTORE_ID, false).setObject(ec, ps, datastoreIdx.getParameterPositionsForOccurrence(j), sms[i].getInternalObjectId());
}
} else if (cmd.getIdentityType() == IdentityType.APPLICATION) {
sms[i].provideFields(cmd.getPKMemberPositions(), new ParameterSetter(sms[i], ps, mappingDefinitions[i]));
}
}
// Execute the statement
ResultSet rs = sqlControl.executeStatementQuery(ec, mconn, statement, ps);
try {
DNStateManager[] missingSMs = processResults(rs, sms);
if (missingSMs != null && missingSMs.length > 0) {
NucleusObjectNotFoundException[] nfes = new NucleusObjectNotFoundException[missingSMs.length];
for (int i = 0; i < nfes.length; i++) {
nfes[i] = new NucleusObjectNotFoundException(Localiser.msg("050018", IdentityUtils.getPersistableIdentityForId(missingSMs[i].getInternalObjectId())));
}
throw new NucleusObjectNotFoundException("Some objects were not found. Look at nested exceptions for details", nfes);
}
} finally {
rs.close();
}
} finally {
sqlControl.closeStatement(mconn, ps);
}
} finally {
mconn.release();
}
} catch (SQLException sqle) {
String msg = Localiser.msg("052220", sms[0].getObjectAsPrintable(), statement, sqle.getMessage());
NucleusLogger.DATASTORE_RETRIEVE.warn(msg);
List exceptions = new ArrayList();
exceptions.add(sqle);
while ((sqle = sqle.getNextException()) != null) {
exceptions.add(sqle);
}
throw new NucleusDataStoreException(msg, (Throwable[]) exceptions.toArray(new Throwable[exceptions.size()]));
}
}
use of org.datanucleus.state.DNStateManager in project datanucleus-rdbms by datanucleus.
the class OracleSerialisedPCMapping method performSetPostProcessing.
/**
* Retrieve the empty BLOB created by the insert statement and write out the current BLOB field value to the Oracle BLOB object
* @param ownerSM the current StateManager
*/
public void performSetPostProcessing(DNStateManager ownerSM) {
Object value = ownerSM.provideField(mmd.getAbsoluteFieldNumber());
DNStateManager sm = null;
if (value != null) {
ExecutionContext ec = ownerSM.getExecutionContext();
sm = ec.findStateManager(value);
if (sm == null || sm.getExecutionContext().getApiAdapter().getExecutionContext(value) == null) {
// Assign a StateManager to the serialised object since none present
sm = ec.getNucleusContext().getStateManagerFactory().newForEmbedded(ec, value, false, ownerSM, mmd.getAbsoluteFieldNumber(), PersistableObjectType.EMBEDDED_PC);
}
}
if (sm != null) {
sm.setStoringPC();
}
// Generate the contents for the BLOB
byte[] bytes = new byte[0];
if (value != null) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(value);
bytes = baos.toByteArray();
} catch (IOException e1) {
// Do Nothing
}
}
// Update the BLOB
if (columnMappings[0] instanceof ColumnMappingPostSet) {
((ColumnMappingPostSet) columnMappings[0]).setPostProcessing(ownerSM, bytes);
}
if (sm != null) {
sm.unsetStoringPC();
}
}
Aggregations