use of org.datanucleus.exceptions.NucleusObjectNotFoundException in project datanucleus-core by datanucleus.
the class StateManagerImpl method checkInheritance.
/**
* Look to the database to determine which class this object is. This parameter is a hint. Set false, if it's
* already determined the correct pcClass for this pc "object" in a certain
* level in the hierarchy. Set to true and it will look to the database.
* TODO This is only called by some outdated code in LDAPUtils; remove it when that is fixed
* @param fv the initial field values of the object.
* @deprecated Dont use this, to be removed
*/
public void checkInheritance(FieldValues fv) {
// Inheritance case, check the level of the instance
ClassLoaderResolver clr = myEC.getClassLoaderResolver();
String className = getStoreManager().getClassNameForObjectID(myID, clr, myEC);
if (className == null) {
// className is null when id class exists, and object has been validated and doesn't exist.
throw new NucleusObjectNotFoundException(Localiser.msg("026013", IdentityUtils.getPersistableIdentityForId(myID)), myID);
} else if (!cmd.getFullClassName().equals(className)) {
Class pcClass;
try {
// load the class and make sure the class is initialized
pcClass = clr.classForName(className, myID.getClass().getClassLoader(), true);
cmd = myEC.getMetaDataManager().getMetaDataForClass(pcClass, clr);
} catch (ClassNotResolvedException e) {
NucleusLogger.PERSISTENCE.warn(Localiser.msg("026014", IdentityUtils.getPersistableIdentityForId(myID)));
throw new NucleusUserException(Localiser.msg("026014", IdentityUtils.getPersistableIdentityForId(myID)), e);
}
if (cmd == null) {
throw new NucleusUserException(Localiser.msg("026012", pcClass)).setFatal();
}
if (cmd.getIdentityType() != IdentityType.APPLICATION) {
throw new NucleusUserException("This method should only be used for objects using application identity.").setFatal();
}
myFP = myEC.getFetchPlan().getFetchPlanForClass(cmd);
int fieldCount = cmd.getMemberCount();
dirtyFields = new boolean[fieldCount];
loadedFields = new boolean[fieldCount];
// Create new PC at right inheritance level
myPC = HELPER.newInstance(pcClass, this);
if (myPC == null) {
throw new NucleusUserException(Localiser.msg("026018", cmd.getFullClassName())).setFatal();
}
// Note that this will mean the fields are loaded twice (loaded earlier in this method)
// and also that postLoad will be called twice
loadFieldValues(fv);
// Create the id for the new PC
myID = myEC.getNucleusContext().getIdentityManager().getApplicationId(myPC, cmd);
}
}
use of org.datanucleus.exceptions.NucleusObjectNotFoundException in project datanucleus-rdbms by datanucleus.
the class PersistableMapping method preDelete.
/**
* Method executed just before the owning object is deleted, allowing tidying up of any relation information.
* @param op ObjectProvider for the owner
*/
public void preDelete(ObjectProvider op) {
int fieldNumber = mmd.getAbsoluteFieldNumber();
if (!op.isFieldLoaded(fieldNumber)) {
// makes sure field is loaded
try {
op.loadField(fieldNumber);
} catch (NucleusObjectNotFoundException onfe) {
// Already deleted so just return
return;
}
}
Object pc = op.provideField(fieldNumber);
pc = mmd.isSingleCollection() ? SCOUtils.singleCollectionValue(getStoreManager().getNucleusContext().getTypeManager(), pc) : pc;
if (pc == null) {
// Null value so nothing to do
return;
}
ExecutionContext ec = op.getExecutionContext();
ClassLoaderResolver clr = ec.getClassLoaderResolver();
// N-1 Uni, so delete join table entry
RelationType relationType = mmd.getRelationType(clr);
if (relationType == RelationType.MANY_TO_ONE_UNI) {
// Update join table entry
PersistableRelationStore store = (PersistableRelationStore) storeMgr.getBackingStoreForField(clr, mmd, mmd.getType());
store.remove(op);
}
// Check if we should delete the related object when this object is deleted
boolean dependent = mmd.isDependent();
if (mmd.isCascadeRemoveOrphans()) {
// JPA allows "orphan removal" to define deletion of the other side
dependent = true;
}
// Check if the field has a FK defined
AbstractMemberMetaData[] relatedMmds = mmd.getRelatedMemberMetaData(clr);
// TODO Cater for more than 1 related field
boolean hasFK = false;
if (!dependent) {
// Not dependent, so check if the datastore has a FK and will take care of it for us
if (mmd.getForeignKeyMetaData() != null) {
hasFK = true;
}
if (RelationType.isBidirectional(relationType) && relatedMmds[0].getForeignKeyMetaData() != null) {
hasFK = true;
}
if (ec.getStringProperty(PropertyNames.PROPERTY_DELETION_POLICY).equals("JDO2")) {
// JDO doesn't currently take note of foreign-key
hasFK = false;
}
}
// There may be some corner cases that this code doesn't yet cater for
if (relationType == RelationType.ONE_TO_ONE_UNI || (relationType == RelationType.ONE_TO_ONE_BI && mmd.getMappedBy() == null)) {
// 1-1 with FK at this side (owner of the relation)
if (dependent) {
boolean relatedObjectDeleted = ec.getApiAdapter().isDeleted(pc);
if (isNullable() && !relatedObjectDeleted) {
// Other object not yet deleted, but the field is nullable so just null out the FK
// TODO Not doing this would cause errors in 1-1 uni relations (e.g AttachDetachTest)
// TODO Log this since it affects the resultant objects
op.replaceFieldMakeDirty(fieldNumber, null);
storeMgr.getPersistenceHandler().updateObject(op, new int[] { fieldNumber });
if (!relatedObjectDeleted) {
// Mark the other object for deletion since not yet tagged
ec.deleteObjectInternal(pc);
}
} else {
// Can't just delete the other object since that would cause a FK constraint violation. Do nothing - handled by DeleteRequest on other object
if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
NucleusLogger.DATASTORE_PERSIST.debug(Localiser.msg("041017", StringUtils.toJVMIDString(op.getObject()), mmd.getFullFieldName()));
}
}
} else {
// We're deleting the FK at this side so shouldn't be an issue
AbstractMemberMetaData relatedMmd = mmd.getRelatedMemberMetaDataForObject(clr, op.getObject(), pc);
if (relatedMmd != null) {
ObjectProvider otherOP = ec.findObjectProvider(pc);
if (otherOP != null) {
// Managed Relations : 1-1 bidir, so null out the object at the other
Object currentValue = otherOP.provideField(relatedMmd.getAbsoluteFieldNumber());
if (currentValue != null) {
if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
NucleusLogger.PERSISTENCE.debug(Localiser.msg("041019", StringUtils.toJVMIDString(pc), relatedMmd.getFullFieldName(), op.getObjectAsPrintable()));
}
otherOP.replaceFieldMakeDirty(relatedMmd.getAbsoluteFieldNumber(), null);
if (ec.getManageRelations()) {
otherOP.getExecutionContext().getRelationshipManager(otherOP).relationChange(relatedMmd.getAbsoluteFieldNumber(), op.getObject(), null);
}
}
}
}
}
} else if (relationType == RelationType.ONE_TO_ONE_BI && mmd.getMappedBy() != null) {
// 1-1 with FK at other side
DatastoreClass relatedTable = storeMgr.getDatastoreClass(relatedMmds[0].getClassName(), clr);
JavaTypeMapping relatedMapping = relatedTable.getMemberMapping(relatedMmds[0]);
boolean isNullable = relatedMapping.isNullable();
ObjectProvider otherOP = ec.findObjectProvider(pc);
if (dependent) {
if (isNullable) {
// Null out the FK in the datastore using a direct update (since we are deleting)
otherOP.replaceFieldMakeDirty(relatedMmds[0].getAbsoluteFieldNumber(), null);
storeMgr.getPersistenceHandler().updateObject(otherOP, new int[] { relatedMmds[0].getAbsoluteFieldNumber() });
}
// Mark the other object for deletion
ec.deleteObjectInternal(pc);
} else if (!hasFK) {
if (isNullable()) {
Object currentRelatedValue = otherOP.provideField(relatedMmds[0].getAbsoluteFieldNumber());
if (currentRelatedValue != null) {
// Null out the FK in the datastore using a direct update (since we are deleting)
otherOP.replaceFieldMakeDirty(relatedMmds[0].getAbsoluteFieldNumber(), null);
storeMgr.getPersistenceHandler().updateObject(otherOP, new int[] { relatedMmds[0].getAbsoluteFieldNumber() });
// Managed Relations : 1-1 bidir, so null out the object at the other
if (ec.getManageRelations()) {
otherOP.getExecutionContext().getRelationshipManager(otherOP).relationChange(relatedMmds[0].getAbsoluteFieldNumber(), op.getObject(), null);
}
}
} else {
// TODO Remove it
}
} else {
// User has a FK defined (in MetaData) so let the datastore take care of it
}
} else if (relationType == RelationType.MANY_TO_ONE_BI) {
ObjectProvider otherOP = ec.findObjectProvider(pc);
if (relatedMmds[0].getJoinMetaData() == null) {
// N-1 with FK at this side
if (otherOP.isDeleting()) {
// Other object is being deleted too but this side has the FK so just delete this object
} else {
// Other object is not being deleted so delete it if necessary
if (dependent) {
if (isNullable()) {
// TODO Datastore nullability info can be unreliable so try to avoid this call
// Null out the FK in the datastore using a direct update (since we are deleting)
op.replaceFieldMakeDirty(fieldNumber, null);
storeMgr.getPersistenceHandler().updateObject(op, new int[] { fieldNumber });
}
if (ec.getApiAdapter().isDeleted(pc)) {
// Object is already tagged for deletion but we're deleting the FK so leave til flush()
} else {
// Mark the other object for deletion
ec.deleteObjectInternal(pc);
}
} else {
// Managed Relations : remove element from collection/map
if (relatedMmds[0].hasCollection()) {
// Only update the other side if not already being deleted
if (!ec.getApiAdapter().isDeleted(otherOP.getObject()) && !otherOP.isDeleting()) {
// Make sure the other object is updated in any caches
ec.markDirty(otherOP, false);
// Make sure collection field is loaded
otherOP.isLoaded(relatedMmds[0].getAbsoluteFieldNumber());
Collection otherColl = (Collection) otherOP.provideField(relatedMmds[0].getAbsoluteFieldNumber());
if (otherColl != null) {
if (ec.getManageRelations()) {
otherOP.getExecutionContext().getRelationshipManager(otherOP).relationRemove(relatedMmds[0].getAbsoluteFieldNumber(), op.getObject());
}
// TODO Localise this message
NucleusLogger.PERSISTENCE.debug("ManagedRelationships : delete of object causes removal from collection at " + relatedMmds[0].getFullFieldName());
otherColl.remove(op.getObject());
}
}
} else if (relatedMmds[0].hasMap()) {
// TODO Cater for maps, but what is the key/value pair ?
}
}
}
} else {
// N-1 with join table so no FK here so need to remove from Collection/Map first? (managed relations)
if (dependent) {
// Mark the other object for deletion
ec.deleteObjectInternal(pc);
} else {
// Managed Relations : remove element from collection/map
if (relatedMmds[0].hasCollection()) {
// Only update the other side if not already being deleted
if (!ec.getApiAdapter().isDeleted(otherOP.getObject()) && !otherOP.isDeleting()) {
// Make sure the other object is updated in any caches
ec.markDirty(otherOP, false);
// Make sure the other object has the collection loaded so does this change
otherOP.isLoaded(relatedMmds[0].getAbsoluteFieldNumber());
Collection otherColl = (Collection) otherOP.provideField(relatedMmds[0].getAbsoluteFieldNumber());
if (otherColl != null) {
// TODO Localise this
NucleusLogger.PERSISTENCE.debug("ManagedRelationships : delete of object causes removal from collection at " + relatedMmds[0].getFullFieldName());
otherColl.remove(op.getObject());
}
}
} else if (relatedMmds[0].hasMap()) {
// TODO Cater for maps, but what is the key/value pair ?
}
}
}
} else if (relationType == RelationType.MANY_TO_ONE_UNI) {
// N-1 uni with join table
if (dependent) {
// Mark the other object for deletion
ec.deleteObjectInternal(pc);
}
} else {
// No relation so what is this field ?
}
}
use of org.datanucleus.exceptions.NucleusObjectNotFoundException in project datanucleus-rdbms by datanucleus.
the class OracleBlobRDBMSMapping method updateBlobColumn.
/**
* Convenience method to update the contents of a BLOB column.
* Oracle requires that a BLOB is initialised with EMPTY_BLOB() and then you retrieve
* the column and update its BLOB value. Performs a statement
* <pre>
* SELECT {blobColumn} FROM TABLE WHERE ID=? FOR UPDATE
* </pre>
* and then updates the Blob value returned.
* @param op ObjectProvider of the object
* @param table Table storing the BLOB column
* @param mapping Datastore mapping for the BLOB column
* @param bytes The bytes to store in the BLOB
* @throws NucleusObjectNotFoundException thrown if an object isnt found
* @throws NucleusDataStoreException thrown if an error occurs in datastore communication
*/
@SuppressWarnings("deprecation")
public static void updateBlobColumn(ObjectProvider op, Table table, DatastoreMapping mapping, byte[] bytes) {
ExecutionContext ec = op.getExecutionContext();
RDBMSStoreManager storeMgr = table.getStoreManager();
// Don't support join tables yet
DatastoreClass classTable = (DatastoreClass) table;
SQLExpressionFactory exprFactory = storeMgr.getSQLExpressionFactory();
// Generate "SELECT {blobColumn} FROM TABLE WHERE ID=? FOR UPDATE" statement
SelectStatement sqlStmt = new SelectStatement(storeMgr, table, null, null);
sqlStmt.setClassLoaderResolver(ec.getClassLoaderResolver());
sqlStmt.addExtension(SQLStatement.EXTENSION_LOCK_FOR_UPDATE, true);
SQLTable blobSqlTbl = SQLStatementHelper.getSQLTableForMappingOfTable(sqlStmt, sqlStmt.getPrimaryTable(), mapping.getJavaTypeMapping());
sqlStmt.select(blobSqlTbl, mapping.getColumn(), null);
StatementClassMapping mappingDefinition = new StatementClassMapping();
AbstractClassMetaData cmd = op.getClassMetaData();
int inputParamNum = 1;
if (cmd.getIdentityType() == IdentityType.DATASTORE) {
// Datastore identity value for input
JavaTypeMapping datastoreIdMapping = classTable.getSurrogateMapping(SurrogateColumnType.DATASTORE_ID, false);
SQLExpression expr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), datastoreIdMapping);
SQLExpression val = exprFactory.newLiteralParameter(sqlStmt, datastoreIdMapping, null, "ID");
sqlStmt.whereAnd(expr.eq(val), true);
StatementMappingIndex datastoreIdx = mappingDefinition.getMappingForMemberPosition(SurrogateColumnType.DATASTORE_ID.getFieldNumber());
if (datastoreIdx == null) {
datastoreIdx = new StatementMappingIndex(datastoreIdMapping);
mappingDefinition.addMappingForMember(SurrogateColumnType.DATASTORE_ID.getFieldNumber(), datastoreIdx);
}
datastoreIdx.addParameterOccurrence(new int[] { inputParamNum });
} else if (cmd.getIdentityType() == IdentityType.APPLICATION) {
// Application identity value(s) for input
int[] pkNums = cmd.getPKMemberPositions();
for (int i = 0; i < pkNums.length; i++) {
AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(pkNums[i]);
JavaTypeMapping pkMapping = classTable.getMemberMapping(mmd);
SQLExpression expr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), pkMapping);
SQLExpression val = exprFactory.newLiteralParameter(sqlStmt, pkMapping, null, "PK" + i);
sqlStmt.whereAnd(expr.eq(val), true);
StatementMappingIndex pkIdx = mappingDefinition.getMappingForMemberPosition(pkNums[i]);
if (pkIdx == null) {
pkIdx = new StatementMappingIndex(pkMapping);
mappingDefinition.addMappingForMember(pkNums[i], pkIdx);
}
int[] inputParams = new int[pkMapping.getNumberOfDatastoreMappings()];
for (int j = 0; j < pkMapping.getNumberOfDatastoreMappings(); j++) {
inputParams[j] = inputParamNum++;
}
pkIdx.addParameterOccurrence(inputParams);
}
}
String textStmt = sqlStmt.getSQLText().toSQL();
if (op.isEmbedded()) {
// This mapping is embedded, so navigate back to the real owner since that is the "id" in the table
ObjectProvider[] embeddedOwners = ec.getOwnersForEmbeddedObjectProvider(op);
if (embeddedOwners != null) {
// Just use the first owner
// TODO Should check if the owner is stored in this table
op = embeddedOwners[0];
}
}
try {
ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
SQLController sqlControl = storeMgr.getSQLController();
try {
PreparedStatement ps = sqlControl.getStatementForQuery(mconn, textStmt);
try {
// Provide the primary key field(s) to the JDBC statement
if (cmd.getIdentityType() == IdentityType.DATASTORE) {
StatementMappingIndex datastoreIdx = mappingDefinition.getMappingForMemberPosition(SurrogateColumnType.DATASTORE_ID.getFieldNumber());
for (int i = 0; i < datastoreIdx.getNumberOfParameterOccurrences(); i++) {
classTable.getSurrogateMapping(SurrogateColumnType.DATASTORE_ID, false).setObject(ec, ps, datastoreIdx.getParameterPositionsForOccurrence(i), op.getInternalObjectId());
}
} else if (cmd.getIdentityType() == IdentityType.APPLICATION) {
op.provideFields(cmd.getPKMemberPositions(), new ParameterSetter(op, ps, mappingDefinition));
}
ResultSet rs = sqlControl.executeStatementQuery(ec, mconn, textStmt, ps);
try {
if (!rs.next()) {
throw new NucleusObjectNotFoundException("No such database row", op.getInternalObjectId());
}
DatastoreAdapter dba = storeMgr.getDatastoreAdapter();
int jdbcMajorVersion = dba.getDriverMajorVersion();
if (dba.getDatastoreDriverName().equalsIgnoreCase(OracleAdapter.OJDBC_DRIVER_NAME) && jdbcMajorVersion < 10) {
// Oracle JDBC drivers version 9 and below use some sh*tty Oracle-specific BLOB type
// we have to cast to that, face west, pray whilst saying ommmmmmmmmmm
oracle.sql.BLOB blob = null;
if (jdbcMajorVersion <= 8) {
OracleResultSet ors = (OracleResultSet) rs;
blob = ors.getBLOB(1);
} else {
blob = (oracle.sql.BLOB) rs.getBlob(1);
}
if (blob != null) {
// Deprecated but what can you do
blob.putBytes(1, bytes);
}
} else {
// Oracle JDBC drivers 10 and above supposedly use the JDBC standard class for Blobs
java.sql.Blob blob = rs.getBlob(1);
if (blob != null) {
blob.setBytes(1, bytes);
}
}
} finally {
rs.close();
}
} finally {
sqlControl.closeStatement(mconn, ps);
}
} finally {
mconn.release();
}
} catch (SQLException e) {
throw new NucleusDataStoreException("Update of BLOB value failed: " + textStmt, e);
}
}
use of org.datanucleus.exceptions.NucleusObjectNotFoundException in project datanucleus-core by datanucleus.
the class StateManagerImpl method attach.
/**
* Method to attach the object managed by this StateManager.
* @param embedded Whether it is embedded
*/
public void attach(boolean embedded) {
if (isAttaching()) {
return;
}
setAttaching(true);
try {
// Check if the object is already persisted
boolean persistent = false;
if (embedded) {
persistent = true;
} else {
if (!myEC.getBooleanProperty(PropertyNames.PROPERTY_ATTACH_SAME_DATASTORE)) {
// We cant assume that this object was detached from this datastore so we check it
try {
locate();
persistent = true;
} catch (NucleusObjectNotFoundException onfe) {
// Not currently present!
}
} else {
// Assumed detached from this datastore
persistent = true;
}
}
// Call any "pre-attach" listeners
getCallbackHandler().preAttach(myPC);
// Retrieve the updated values from the detached object
replaceStateManager(myPC, this);
retrieveDetachState(this);
if (!persistent) {
// Persist the object into this datastore first
makePersistent();
}
// Migrate the lifecycle state to persistent
myLC = myLC.transitionAttach(this);
// Make sure the attached object goes in the cache
// [would not get cached when not changed if we didnt do this here]
myEC.putObjectIntoLevel1Cache(this);
int[] attachFieldNumbers = getFieldNumbersOfLoadedOrDirtyFields(loadedFields, dirtyFields);
if (attachFieldNumbers != null) {
// Only update the fields that were detached, and only update them if there are any to update
NucleusLogger.GENERAL.debug("Attaching id=" + getInternalObjectId() + " fields=" + StringUtils.intArrayToString(attachFieldNumbers));
provideFields(attachFieldNumbers, new AttachFieldManager(this, cmd.getSCOMutableMemberFlags(), dirtyFields, persistent, true, false));
}
// Call any "post-attach" listeners
getCallbackHandler().postAttach(myPC, myPC);
} finally {
setAttaching(false);
}
}
use of org.datanucleus.exceptions.NucleusObjectNotFoundException in project datanucleus-core by datanucleus.
the class AbstractPersistenceHandler method findObjectForUnique.
/* (non-Javadoc)
* @see org.datanucleus.store.StorePersistenceHandler#findObjectForUnique(org.datanucleus.ExecutionContext, org.datanucleus.metadata.AbstractClassMetaData, java.lang.String[], java.lang.Object[])
*/
@Override
public Object findObjectForUnique(ExecutionContext ec, AbstractClassMetaData cmd, String[] memberNames, Object[] values) {
if (memberNames.length != values.length) {
throw new NucleusUserException("findObjectForUnique should have same number of member names and values");
}
// Fallback to using a simple JDOQL query (which is what would be performed for the majority of datastores anyway)
StringBuilder jdoqlStr = new StringBuilder("SELECT FROM ").append(cmd.getFullClassName()).append(" WHERE ");
Map<String, Object> paramValueMap = new HashMap<>();
for (int i = 0; i < memberNames.length; i++) {
jdoqlStr.append("this.").append(memberNames[i]).append(" == :val").append(i);
paramValueMap.put("val" + i, values[i]);
if (i != memberNames.length - 1) {
jdoqlStr.append(" && ");
}
}
Query q = storeMgr.newQuery(Query.LANGUAGE_JDOQL, ec, jdoqlStr.toString());
List results = (List) q.executeWithMap(paramValueMap);
if (results == null || results.size() == 0) {
throw new NucleusObjectNotFoundException("No object found for specified members and values of type " + cmd.getFullClassName());
} else if (results.size() == 1) {
return results.get(0);
}
throw new NucleusUserException("Specified members for class " + cmd.getFullClassName() + " finds multiple objects!");
}
Aggregations