use of org.datanucleus.state.ObjectProvider in project datanucleus-rdbms by datanucleus.
the class OracleCollectionMapping method postInsert.
/**
* Retrieve the empty BLOB created by the insert statement and write out the
* current BLOB field value to the Oracle BLOB object.
* @param ownerOP ObjectProvider of the owner
*/
public void postInsert(ObjectProvider ownerOP) {
if (containerIsStoredInSingleColumn()) {
ExecutionContext ec = ownerOP.getExecutionContext();
Collection value = (Collection) ownerOP.provideField(mmd.getAbsoluteFieldNumber());
if (value != null) {
if (mmd.getCollection().elementIsPersistent()) {
// Make sure all persistable elements have ObjectProviders
Object[] collElements = value.toArray();
for (Object elem : collElements) {
if (elem != null) {
ObjectProvider elemOP = ec.findObjectProvider(elem);
if (elemOP == null || ec.getApiAdapter().getExecutionContext(elem) == null) {
elemOP = ec.getNucleusContext().getObjectProviderFactory().newForEmbedded(ec, elem, false, ownerOP, mmd.getAbsoluteFieldNumber());
}
}
}
}
}
// 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
OracleBlobRDBMSMapping.updateBlobColumn(ownerOP, getTable(), getDatastoreMapping(0), bytes);
} else {
super.postInsert(ownerOP);
}
}
use of org.datanucleus.state.ObjectProvider in project datanucleus-rdbms by datanucleus.
the class SerialisedReferenceMapping method setObject.
/**
* Method to populate parameter positions in a PreparedStatement with this object
* @param ec execution context
* @param ps The Prepared Statement
* @param exprIndex The parameter positions to populate
* @param value The value of the PC to use in populating the parameter positions
* @param ownerOP ObjectProvider for the owning object
* @param fieldNumber field number of this object in the owning object
*/
public void setObject(ExecutionContext ec, PreparedStatement ps, int[] exprIndex, Object value, ObjectProvider ownerOP, int fieldNumber) {
ApiAdapter api = ec.getApiAdapter();
if (api.isPersistable(value)) {
// Assign a StateManager to the serialised object if none present
ObjectProvider embSM = ec.findObjectProvider(value);
if (embSM == null || api.getExecutionContext(value) == null) {
embSM = ec.getNucleusContext().getObjectProviderFactory().newForEmbedded(ec, value, false, ownerOP, fieldNumber);
}
}
ObjectProvider sm = null;
if (api.isPersistable(value)) {
// Find SM for serialised PC object
sm = ec.findObjectProvider(value);
}
if (sm != null) {
sm.setStoringPC();
}
getDatastoreMapping(0).setObject(ps, exprIndex[0], value);
if (sm != null) {
sm.unsetStoringPC();
}
}
use of org.datanucleus.state.ObjectProvider in project datanucleus-rdbms by datanucleus.
the class FKArrayStore method iterator.
/**
* Accessor for an iterator for the set.
* @param ownerOP ObjectProvider for the set.
* @return Iterator for the set.
*/
public Iterator<E> iterator(ObjectProvider ownerOP) {
ExecutionContext ec = ownerOP.getExecutionContext();
if (elementInfo == null || elementInfo.length == 0) {
return null;
}
// Generate the statement, and statement mapping/parameter information
IteratorStatement iterStmt = getIteratorStatement(ownerOP.getExecutionContext(), ownerOP.getExecutionContext().getFetchPlan(), true);
SelectStatement sqlStmt = iterStmt.getSelectStatement();
StatementClassMapping iteratorMappingDef = iterStmt.getStatementClassMapping();
// Input parameter(s) - the owner
int inputParamNum = 1;
StatementMappingIndex ownerIdx = new StatementMappingIndex(ownerMapping);
if (sqlStmt.getNumberOfUnions() > 0) {
// Add parameter occurrence for each union of statement
for (int j = 0; j < sqlStmt.getNumberOfUnions() + 1; j++) {
int[] paramPositions = new int[ownerMapping.getNumberOfDatastoreMappings()];
for (int k = 0; k < ownerMapping.getNumberOfDatastoreMappings(); k++) {
paramPositions[k] = inputParamNum++;
}
ownerIdx.addParameterOccurrence(paramPositions);
}
} else {
int[] paramPositions = new int[ownerMapping.getNumberOfDatastoreMappings()];
for (int k = 0; k < ownerMapping.getNumberOfDatastoreMappings(); k++) {
paramPositions[k] = inputParamNum++;
}
ownerIdx.addParameterOccurrence(paramPositions);
}
StatementParameterMapping iteratorMappingParams = new StatementParameterMapping();
iteratorMappingParams.addMappingForParameter("owner", ownerIdx);
if (ec.getTransaction().getSerializeRead() != null && ec.getTransaction().getSerializeRead()) {
sqlStmt.addExtension(SQLStatement.EXTENSION_LOCK_FOR_UPDATE, true);
}
String stmt = sqlStmt.getSQLText().toSQL();
try {
ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
SQLController sqlControl = storeMgr.getSQLController();
try {
// Create the statement
PreparedStatement ps = sqlControl.getStatementForQuery(mconn, stmt);
// Set the owner
ObjectProvider stmtOwnerOP = BackingStoreHelper.getOwnerObjectProviderForBackingStore(ownerOP);
int numParams = ownerIdx.getNumberOfParameterOccurrences();
for (int paramInstance = 0; paramInstance < numParams; paramInstance++) {
ownerIdx.getMapping().setObject(ec, ps, ownerIdx.getParameterPositionsForOccurrence(paramInstance), stmtOwnerOP.getObject());
}
try {
ResultSet rs = sqlControl.executeStatementQuery(ec, mconn, stmt, ps);
try {
ResultObjectFactory rof = null;
if (elementsAreEmbedded || elementsAreSerialised) {
throw new NucleusException("Cannot have FK array with non-persistent objects");
}
rof = new PersistentClassROF(ec, rs, false, iteratorMappingDef, elementCmd, clr.classForName(elementType));
return new ArrayStoreIterator(ownerOP, rs, rof, this);
} finally {
rs.close();
}
} finally {
sqlControl.closeStatement(mconn, ps);
}
} finally {
mconn.release();
}
} catch (SQLException | MappedDatastoreException e) {
throw new NucleusDataStoreException(Localiser.msg("056006", stmt), e);
}
}
use of org.datanucleus.state.ObjectProvider in project datanucleus-rdbms by datanucleus.
the class FKListStore method validateElementForWriting.
/**
* Method to validate that an element is valid for writing to the datastore.
* TODO Minimise differences to super.validateElementForWriting()
* @param op ObjectProvider for the List
* @param element The element to validate
* @param index The position that the element is being stored at in the list
* @return Whether the element was inserted
*/
protected boolean validateElementForWriting(final ObjectProvider op, final Object element, final int index) {
final Object newOwner = op.getObject();
ComponentInfo info = getComponentInfoForElement(element);
final DatastoreClass elementTable;
if (storeMgr.getNucleusContext().getMetaDataManager().isPersistentInterface(elementType)) {
elementTable = storeMgr.getDatastoreClass(storeMgr.getNucleusContext().getMetaDataManager().getImplementationNameForPersistentInterface(elementType), clr);
} else {
elementTable = storeMgr.getDatastoreClass(element.getClass().getName(), clr);
}
final JavaTypeMapping orderMapping;
if (info != null) {
orderMapping = info.getDatastoreClass().getExternalMapping(ownerMemberMetaData, MappingType.EXTERNAL_INDEX);
} else {
orderMapping = this.orderMapping;
}
// Check if element is ok for use in the datastore, specifying any external mappings that may be required
boolean inserted = super.validateElementForWriting(op.getExecutionContext(), element, new FieldValues() {
public void fetchFields(ObjectProvider elemOP) {
// Find the (element) table storing the FK back to the owner
if (elementTable != null) {
JavaTypeMapping externalFKMapping = elementTable.getExternalMapping(ownerMemberMetaData, MappingType.EXTERNAL_FK);
if (externalFKMapping != null) {
// The element has an external FK mapping so set the value it needs to use in the INSERT
elemOP.setAssociatedValue(externalFKMapping, op.getObject());
}
if (relationDiscriminatorMapping != null) {
elemOP.setAssociatedValue(relationDiscriminatorMapping, relationDiscriminatorValue);
}
if (orderMapping != null && index >= 0) {
if (ownerMemberMetaData.getOrderMetaData() != null && ownerMemberMetaData.getOrderMetaData().getMappedBy() != null) {
// Order is stored in a field in the element so update it
// We support mapped-by fields of types int/long/Integer/Long currently
Object indexValue = null;
if (orderMapping.getMemberMetaData().getTypeName().equals(ClassNameConstants.JAVA_LANG_LONG) || orderMapping.getMemberMetaData().getTypeName().equals(ClassNameConstants.LONG)) {
indexValue = Long.valueOf(index);
} else {
indexValue = Integer.valueOf(index);
}
elemOP.replaceFieldMakeDirty(orderMapping.getMemberMetaData().getAbsoluteFieldNumber(), indexValue);
} else {
// Order is stored in a surrogate column so save its vaue for the element to use later
elemOP.setAssociatedValue(orderMapping, Integer.valueOf(index));
}
}
}
if (ownerMemberMetaData.getMappedBy() != null) {
// TODO This is ManagedRelations - move into RelationshipManager
// Managed Relations : 1-N bidir, so make sure owner is correct at persist
// TODO Support DOT notation in mappedBy
ObjectProvider ownerHolderOP = elemOP;
int ownerFieldNumberInHolder = -1;
if (ownerMemberMetaData.getMappedBy().indexOf('.') > 0) {
AbstractMemberMetaData otherMmd = null;
AbstractClassMetaData otherCmd = info.getAbstractClassMetaData();
String remainingMappedBy = ownerMemberMetaData.getMappedBy();
while (remainingMappedBy.indexOf('.') > 0) {
int dotPosition = remainingMappedBy.indexOf('.');
String thisMappedBy = remainingMappedBy.substring(0, dotPosition);
otherMmd = otherCmd.getMetaDataForMember(thisMappedBy);
Object holderValueAtField = ownerHolderOP.provideField(otherMmd.getAbsoluteFieldNumber());
ownerHolderOP = op.getExecutionContext().findObjectProviderForEmbedded(holderValueAtField, ownerHolderOP, otherMmd);
remainingMappedBy = remainingMappedBy.substring(dotPosition + 1);
otherCmd = storeMgr.getMetaDataManager().getMetaDataForClass(otherMmd.getTypeName(), clr);
if (remainingMappedBy.indexOf('.') < 0) {
otherMmd = otherCmd.getMetaDataForMember(remainingMappedBy);
ownerFieldNumberInHolder = otherMmd.getAbsoluteFieldNumber();
}
}
} else {
ownerFieldNumberInHolder = info.getAbstractClassMetaData().getAbsolutePositionOfMember(ownerMemberMetaData.getMappedBy());
}
Object currentOwner = ownerHolderOP.provideField(ownerFieldNumberInHolder);
if (currentOwner == null) {
// No owner, so correct it
NucleusLogger.PERSISTENCE.info(Localiser.msg("056037", op.getObjectAsPrintable(), ownerMemberMetaData.getFullFieldName(), StringUtils.toJVMIDString(ownerHolderOP.getObject())));
ownerHolderOP.replaceFieldMakeDirty(ownerFieldNumberInHolder, newOwner);
} else if (currentOwner != newOwner && op.getReferencedPC() == null) {
// Inconsistent owner, so throw exception
throw new NucleusUserException(Localiser.msg("056038", op.getObjectAsPrintable(), ownerMemberMetaData.getFullFieldName(), StringUtils.toJVMIDString(ownerHolderOP.getObject()), StringUtils.toJVMIDString(currentOwner)));
}
}
}
public void fetchNonLoadedFields(ObjectProvider op) {
}
public FetchPlan getFetchPlanForLoading() {
return null;
}
});
return inserted;
}
use of org.datanucleus.state.ObjectProvider in project datanucleus-rdbms by datanucleus.
the class FKListStore method listIterator.
/**
* Accessor for an iterator through the list elements.
* @param ownerOP ObjectProvider for the owner.
* @param startIdx The start index in the list (only for indexed lists)
* @param endIdx The end index in the list (only for indexed lists)
* @return The List Iterator
*/
protected ListIterator<E> listIterator(ObjectProvider ownerOP, int startIdx, int endIdx) {
ExecutionContext ec = ownerOP.getExecutionContext();
Transaction tx = ec.getTransaction();
if (elementInfo == null || elementInfo.length == 0) {
return null;
}
// Generate the statement. Note that this is not cached since depends on the current FetchPlan and other things
IteratorStatement iterStmt = getIteratorStatement(ownerOP.getExecutionContext(), ec.getFetchPlan(), true, startIdx, endIdx);
SelectStatement sqlStmt = iterStmt.getSelectStatement();
StatementClassMapping resultMapping = iterStmt.getStatementClassMapping();
// Input parameter(s) - the owner
int inputParamNum = 1;
StatementMappingIndex ownerIdx = new StatementMappingIndex(ownerMapping);
if (sqlStmt.getNumberOfUnions() > 0) {
// Add parameter occurrence for each union of statement
for (int j = 0; j < sqlStmt.getNumberOfUnions() + 1; j++) {
int[] paramPositions = new int[ownerMapping.getNumberOfDatastoreMappings()];
for (int k = 0; k < ownerMapping.getNumberOfDatastoreMappings(); k++) {
paramPositions[k] = inputParamNum++;
}
ownerIdx.addParameterOccurrence(paramPositions);
}
} else {
int[] paramPositions = new int[ownerMapping.getNumberOfDatastoreMappings()];
for (int k = 0; k < ownerMapping.getNumberOfDatastoreMappings(); k++) {
paramPositions[k] = inputParamNum++;
}
ownerIdx.addParameterOccurrence(paramPositions);
}
if (tx.getSerializeRead() != null && tx.getSerializeRead()) {
sqlStmt.addExtension(SQLStatement.EXTENSION_LOCK_FOR_UPDATE, true);
}
String stmt = sqlStmt.getSQLText().toSQL();
try {
ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
SQLController sqlControl = storeMgr.getSQLController();
try {
// Create the statement
PreparedStatement ps = sqlControl.getStatementForQuery(mconn, stmt);
// Set the owner
ObjectProvider stmtOwnerOP = BackingStoreHelper.getOwnerObjectProviderForBackingStore(ownerOP);
int numParams = ownerIdx.getNumberOfParameterOccurrences();
for (int paramInstance = 0; paramInstance < numParams; paramInstance++) {
ownerIdx.getMapping().setObject(ec, ps, ownerIdx.getParameterPositionsForOccurrence(paramInstance), stmtOwnerOP.getObject());
}
try {
ResultSet rs = sqlControl.executeStatementQuery(ec, mconn, stmt, ps);
try {
ResultObjectFactory rof = null;
if (elementsAreEmbedded || elementsAreSerialised) {
throw new NucleusException("Cannot have FK set with non-persistent objects");
}
rof = new PersistentClassROF(ec, rs, false, resultMapping, elementCmd, clr.classForName(elementType));
return new ListStoreIterator(ownerOP, rs, rof, this);
} finally {
rs.close();
}
} finally {
sqlControl.closeStatement(mconn, ps);
}
} finally {
mconn.release();
}
} catch (SQLException | MappedDatastoreException e) {
throw new NucleusDataStoreException(Localiser.msg("056006", stmt), e);
}
}
Aggregations