use of org.datanucleus.store.rdbms.table.DatastoreClass in project datanucleus-rdbms by datanucleus.
the class RDBMSPersistenceHandler method insertObject.
/**
* Inserts a persistent object into the database.
* The insert can take place in several steps, one insert per table that it is stored in.
* e.g When persisting an object that uses "new-table" inheritance for each level of the inheritance tree
* then will get an INSERT into each table. When persisting an object that uses "complete-table"
* inheritance then will get a single INSERT into its table.
* @param op The ObjectProvider of the object to be inserted.
* @throws NucleusDataStoreException when an error occurs in the datastore communication
*/
public void insertObject(ObjectProvider op) {
// Check if read-only so update not permitted
assertReadOnlyForUpdateOfObject(op);
// Check if we need to do any updates to the schema before inserting this object
checkForSchemaUpdatesForFieldsOfObject(op, op.getLoadedFieldNumbers());
ExecutionContext ec = op.getExecutionContext();
ClassLoaderResolver clr = op.getExecutionContext().getClassLoaderResolver();
String className = op.getClassMetaData().getFullClassName();
DatastoreClass dc = getDatastoreClass(className, clr);
if (dc == null) {
if (op.getClassMetaData().getInheritanceMetaData().getStrategy() == InheritanceStrategy.SUBCLASS_TABLE) {
throw new NucleusUserException(Localiser.msg("032013", className));
}
throw new NucleusException(Localiser.msg("032014", className, op.getClassMetaData().getInheritanceMetaData().getStrategy())).setFatal();
}
if (ec.getStatistics() != null) {
ec.getStatistics().incrementInsertCount();
}
insertObjectInTable(dc, op, clr);
}
use of org.datanucleus.store.rdbms.table.DatastoreClass in project datanucleus-rdbms by datanucleus.
the class RDBMSPersistenceHandler method locateObject.
/**
* Locates this object in the datastore.
* @param op ObjectProvider for the object to be found
* @throws NucleusObjectNotFoundException if the object doesnt exist
* @throws NucleusDataStoreException when an error occurs in the datastore communication
*/
public void locateObject(ObjectProvider op) {
ClassLoaderResolver clr = op.getExecutionContext().getClassLoaderResolver();
DatastoreClass table = getDatastoreClass(op.getObject().getClass().getName(), clr);
getLocateRequest(table, op.getObject().getClass().getName()).execute(op);
}
use of org.datanucleus.store.rdbms.table.DatastoreClass in project datanucleus-rdbms by datanucleus.
the class RDBMSPersistenceHandler method fetchObject.
// ------------------------------ Fetch ----------------------------------
/**
* Fetches (fields of) a persistent object from the database.
* This does a single SELECT on the candidate of the class in question. Will join to inherited
* tables as appropriate to get values persisted into other tables. Can also join to the tables of
* related objects (1-1, N-1) as neccessary to retrieve those objects.
* @param op Object Provider of the object to be fetched.
* @param memberNumbers The numbers of the members to be fetched.
* @throws NucleusObjectNotFoundException if the object doesn't exist
* @throws NucleusDataStoreException when an error occurs in the datastore communication
*/
public void fetchObject(ObjectProvider op, int[] memberNumbers) {
ExecutionContext ec = op.getExecutionContext();
ClassLoaderResolver clr = ec.getClassLoaderResolver();
// Extract metadata of members to process
AbstractMemberMetaData[] mmds = null;
if (memberNumbers != null && memberNumbers.length > 0) {
int[] memberNumbersToProcess = memberNumbers;
AbstractClassMetaData cmd = op.getClassMetaData();
if (storeMgr.getBooleanProperty(RDBMSPropertyNames.PROPERTY_RDBMS_FETCH_UNLOADED_AUTO)) {
// Here we simply load up any unloaded non-relation or 1-1/N-1 members
if (!op.getLifecycleState().isDeleted()) {
// Check if this will actually do a SELECT (because we don't want to impose that if not otherwise)
boolean fetchPerformsSelect = false;
for (int i = 0; i < memberNumbers.length; i++) {
AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(memberNumbers[i]);
RelationType relationType = mmd.getRelationType(clr);
if (relationType != RelationType.ONE_TO_MANY_UNI && relationType != RelationType.ONE_TO_MANY_BI && relationType != RelationType.MANY_TO_MANY_BI) {
fetchPerformsSelect = true;
break;
}
}
if (fetchPerformsSelect) {
// Definitely does a SELECT, so try to identify any additional non-relation or 1-1, N-1
// members that aren't loaded that could be fetched right now in this call.
List<Integer> memberNumberList = new ArrayList<>();
for (int i = 0; i < memberNumbers.length; i++) {
memberNumberList.add(memberNumbers[i]);
}
// Check if we could retrieve any other unloaded fields in this call
boolean[] loadedFlags = op.getLoadedFields();
for (int i = 0; i < loadedFlags.length; i++) {
boolean requested = false;
for (int j = 0; j < memberNumbers.length; j++) {
if (memberNumbers[j] == i) {
requested = true;
break;
}
}
if (!requested && !loadedFlags[i]) {
AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(i);
RelationType relType = mmd.getRelationType(clr);
if (relType == RelationType.NONE || relType == RelationType.ONE_TO_ONE_BI || relType == RelationType.ONE_TO_ONE_UNI) {
memberNumberList.add(i);
}
}
}
memberNumbersToProcess = new int[memberNumberList.size()];
int i = 0;
Iterator<Integer> fieldNumberIter = memberNumberList.iterator();
while (fieldNumberIter.hasNext()) {
memberNumbersToProcess[i++] = fieldNumberIter.next();
}
}
}
}
// Convert the field numbers for this class into their metadata for the class
mmds = new AbstractMemberMetaData[memberNumbersToProcess.length];
for (int i = 0; i < mmds.length; i++) {
mmds[i] = cmd.getMetaDataForManagedMemberAtAbsolutePosition(memberNumbersToProcess[i]);
}
}
if (op.isEmbedded()) {
StringBuilder str = new StringBuilder();
if (mmds != null) {
for (int i = 0; i < mmds.length; i++) {
if (i > 0) {
str.append(',');
}
str.append(mmds[i].getName());
}
}
NucleusLogger.PERSISTENCE.info("Request to load fields \"" + str.toString() + "\" of class " + op.getClassMetaData().getFullClassName() + " but object is embedded, so ignored");
} else {
if (ec.getStatistics() != null) {
ec.getStatistics().incrementFetchCount();
}
DatastoreClass table = getDatastoreClass(op.getClassMetaData().getFullClassName(), clr);
Request req = getFetchRequest(table, mmds, op.getClassMetaData(), clr);
req.execute(op);
}
}
use of org.datanucleus.store.rdbms.table.DatastoreClass in project datanucleus-rdbms by datanucleus.
the class RDBMSStoreHelper method getClassNameForIdUsingDiscriminator.
/**
* Utility that does a discriminator candidate query for the specified candidate and subclasses
* and returns the class name of the instance that has the specified identity (if any).
* @param storeMgr RDBMS StoreManager
* @param ec execution context
* @param id The id
* @param cmd Metadata for the root candidate class
* @return Name of the class with this identity (or null if none found)
*/
public static String getClassNameForIdUsingDiscriminator(RDBMSStoreManager storeMgr, ExecutionContext ec, Object id, AbstractClassMetaData cmd) {
// Check for input error
if (cmd == null || id == null) {
return null;
}
SQLExpressionFactory exprFactory = storeMgr.getSQLExpressionFactory();
ClassLoaderResolver clr = ec.getClassLoaderResolver();
DatastoreClass primaryTable = storeMgr.getDatastoreClass(cmd.getFullClassName(), clr);
// Form the query to find which one of these classes has the instance with this id
DiscriminatorStatementGenerator stmtGen = new DiscriminatorStatementGenerator(storeMgr, clr, clr.classForName(cmd.getFullClassName()), true, null, null);
stmtGen.setOption(SelectStatementGenerator.OPTION_RESTRICT_DISCRIM);
SelectStatement sqlStmt = stmtGen.getStatement(ec);
// Select the discriminator
JavaTypeMapping discrimMapping = primaryTable.getSurrogateMapping(SurrogateColumnType.DISCRIMINATOR, true);
SQLTable discrimSqlTbl = SQLStatementHelper.getSQLTableForMappingOfTable(sqlStmt, sqlStmt.getPrimaryTable(), discrimMapping);
sqlStmt.select(discrimSqlTbl, discrimMapping, null);
// Restrict to this id
JavaTypeMapping idMapping = primaryTable.getIdMapping();
JavaTypeMapping idParamMapping = new PersistableIdMapping((PersistableMapping) idMapping);
SQLExpression sqlFldExpr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), idMapping);
SQLExpression sqlFldVal = exprFactory.newLiteralParameter(sqlStmt, idParamMapping, id, "ID");
sqlStmt.whereAnd(sqlFldExpr.eq(sqlFldVal), true);
// Perform the query
try {
ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
SQLController sqlControl = storeMgr.getSQLController();
if (ec.getSerializeReadForClass(cmd.getFullClassName())) {
sqlStmt.addExtension(SQLStatement.EXTENSION_LOCK_FOR_UPDATE, true);
}
try {
PreparedStatement ps = SQLStatementHelper.getPreparedStatementForSQLStatement(sqlStmt, ec, mconn, null, null);
String statement = sqlStmt.getSQLText().toSQL();
try {
ResultSet rs = sqlControl.executeStatementQuery(ec, mconn, statement, ps);
try {
while (rs.next()) {
DiscriminatorMetaData dismd = discrimMapping.getTable().getDiscriminatorMetaData();
return RDBMSQueryUtils.getClassNameFromDiscriminatorResultSetRow(discrimMapping, dismd, rs, ec);
}
} finally {
rs.close();
}
} finally {
sqlControl.closeStatement(mconn, ps);
}
} finally {
mconn.release();
}
} catch (SQLException sqe) {
NucleusLogger.DATASTORE.error("Exception thrown on querying of discriminator for id", sqe);
throw new NucleusDataStoreException(sqe.toString(), sqe);
}
return null;
}
use of org.datanucleus.store.rdbms.table.DatastoreClass in project datanucleus-rdbms by datanucleus.
the class RDBMSStoreHelper method getClassNameForIdUsingUnion.
/**
* Utility that does a union candidate query for the specified candidate(s) and subclasses
* and returns the class name of the instance that has the specified identity (if any).
* @param storeMgr RDBMS StoreManager
* @param ec execution context
* @param id The id
* @param rootCmds Metadata for the classes at the root
* @return Name of the class with this identity (or null if none found)
*/
public static String getClassNameForIdUsingUnion(RDBMSStoreManager storeMgr, ExecutionContext ec, Object id, List<AbstractClassMetaData> rootCmds) {
// Check for input error
if (rootCmds == null || rootCmds.isEmpty() || id == null) {
return null;
}
SQLExpressionFactory exprFactory = storeMgr.getSQLExpressionFactory();
ClassLoaderResolver clr = ec.getClassLoaderResolver();
// Form a query UNIONing all possible root candidates (and their subclasses)
Iterator<AbstractClassMetaData> rootCmdIter = rootCmds.iterator();
// Metadata for sample class in the tree so we can check if needs locking
AbstractClassMetaData sampleCmd = null;
SelectStatement sqlStmtMain = null;
while (rootCmdIter.hasNext()) {
AbstractClassMetaData rootCmd = rootCmdIter.next();
DatastoreClass rootTbl = storeMgr.getDatastoreClass(rootCmd.getFullClassName(), clr);
InheritanceMetaData rootInhmd = rootCmd.getBaseAbstractClassMetaData().getInheritanceMetaData();
if (rootInhmd.getStrategy() == InheritanceStrategy.COMPLETE_TABLE) {
// COMPLETE TABLE so use one branch of UNION for each possible class
if (rootTbl != null) {
UnionStatementGenerator stmtGen = new UnionStatementGenerator(storeMgr, clr, clr.classForName(rootCmd.getFullClassName()), false, null, null);
stmtGen.setOption(SelectStatementGenerator.OPTION_SELECT_DN_TYPE);
if (sqlStmtMain == null) {
sampleCmd = rootCmd;
sqlStmtMain = stmtGen.getStatement(ec);
// WHERE (object id) = ?
JavaTypeMapping idMapping = sqlStmtMain.getPrimaryTable().getTable().getIdMapping();
JavaTypeMapping idParamMapping = new PersistableIdMapping((PersistableMapping) idMapping);
SQLExpression fieldExpr = exprFactory.newExpression(sqlStmtMain, sqlStmtMain.getPrimaryTable(), idMapping);
SQLExpression fieldVal = exprFactory.newLiteralParameter(sqlStmtMain, idParamMapping, id, "ID");
sqlStmtMain.whereAnd(fieldExpr.eq(fieldVal), true);
} else {
SelectStatement sqlStmt = stmtGen.getStatement(ec);
// WHERE (object id) = ?
JavaTypeMapping idMapping = sqlStmt.getPrimaryTable().getTable().getIdMapping();
JavaTypeMapping idParamMapping = new PersistableIdMapping((PersistableMapping) idMapping);
SQLExpression fieldExpr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), idMapping);
SQLExpression fieldVal = exprFactory.newLiteralParameter(sqlStmt, idParamMapping, id, "ID");
sqlStmt.whereAnd(fieldExpr.eq(fieldVal), true);
sqlStmtMain.union(sqlStmt);
}
}
Collection<String> rootSubclassNames = storeMgr.getSubClassesForClass(rootCmd.getFullClassName(), true, clr);
for (String rootSubclassName : rootSubclassNames) {
AbstractClassMetaData rootSubclassCmd = storeMgr.getMetaDataManager().getMetaDataForClass(rootSubclassName, clr);
DatastoreClass rootSubclassTbl = storeMgr.getDatastoreClass(rootSubclassCmd.getFullClassName(), clr);
if (rootSubclassTbl != null) {
UnionStatementGenerator stmtGen = new UnionStatementGenerator(storeMgr, clr, clr.classForName(rootSubclassCmd.getFullClassName()), false, null, null);
stmtGen.setOption(SelectStatementGenerator.OPTION_SELECT_DN_TYPE);
if (sqlStmtMain == null) {
sampleCmd = rootSubclassCmd;
sqlStmtMain = stmtGen.getStatement(ec);
// WHERE (object id) = ?
JavaTypeMapping idMapping = sqlStmtMain.getPrimaryTable().getTable().getIdMapping();
JavaTypeMapping idParamMapping = new PersistableIdMapping((PersistableMapping) idMapping);
SQLExpression fieldExpr = exprFactory.newExpression(sqlStmtMain, sqlStmtMain.getPrimaryTable(), idMapping);
SQLExpression fieldVal = exprFactory.newLiteralParameter(sqlStmtMain, idParamMapping, id, "ID");
sqlStmtMain.whereAnd(fieldExpr.eq(fieldVal), true);
} else {
SelectStatement sqlStmt = stmtGen.getStatement(ec);
// WHERE (object id) = ?
JavaTypeMapping idMapping = sqlStmt.getPrimaryTable().getTable().getIdMapping();
JavaTypeMapping idParamMapping = new PersistableIdMapping((PersistableMapping) idMapping);
SQLExpression fieldExpr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), idMapping);
SQLExpression fieldVal = exprFactory.newLiteralParameter(sqlStmt, idParamMapping, id, "ID");
sqlStmt.whereAnd(fieldExpr.eq(fieldVal), true);
sqlStmtMain.union(sqlStmt);
}
}
}
continue;
}
if (rootTbl == null) {
// Class must be using "subclass-table" (no table of its own) so find where it is
AbstractClassMetaData[] subcmds = storeMgr.getClassesManagingTableForClass(rootCmd, clr);
if (subcmds == null || subcmds.length == 0) {
// No table for this class so ignore
} else {
for (int i = 0; i < subcmds.length; i++) {
UnionStatementGenerator stmtGen = new UnionStatementGenerator(storeMgr, clr, clr.classForName(subcmds[i].getFullClassName()), true, null, null);
stmtGen.setOption(SelectStatementGenerator.OPTION_SELECT_DN_TYPE);
if (sqlStmtMain == null) {
sampleCmd = subcmds[i];
sqlStmtMain = stmtGen.getStatement(ec);
// WHERE (object id) = ?
JavaTypeMapping idMapping = sqlStmtMain.getPrimaryTable().getTable().getIdMapping();
JavaTypeMapping idParamMapping = new PersistableIdMapping((PersistableMapping) idMapping);
SQLExpression fieldExpr = exprFactory.newExpression(sqlStmtMain, sqlStmtMain.getPrimaryTable(), idMapping);
SQLExpression fieldVal = exprFactory.newLiteralParameter(sqlStmtMain, idParamMapping, id, "ID");
sqlStmtMain.whereAnd(fieldExpr.eq(fieldVal), true);
} else {
SelectStatement sqlStmt = stmtGen.getStatement(ec);
// WHERE (object id) = ?
JavaTypeMapping idMapping = sqlStmt.getPrimaryTable().getTable().getIdMapping();
JavaTypeMapping idParamMapping = new PersistableIdMapping((PersistableMapping) idMapping);
SQLExpression fieldExpr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), idMapping);
SQLExpression fieldVal = exprFactory.newLiteralParameter(sqlStmt, idParamMapping, id, "ID");
sqlStmt.whereAnd(fieldExpr.eq(fieldVal), true);
sqlStmtMain.union(sqlStmt);
}
}
}
} else {
UnionStatementGenerator stmtGen = new UnionStatementGenerator(storeMgr, clr, clr.classForName(rootCmd.getFullClassName()), true, null, null);
stmtGen.setOption(SelectStatementGenerator.OPTION_SELECT_DN_TYPE);
if (sqlStmtMain == null) {
sampleCmd = rootCmd;
sqlStmtMain = stmtGen.getStatement(ec);
// WHERE (object id) = ?
JavaTypeMapping idMapping = sqlStmtMain.getPrimaryTable().getTable().getIdMapping();
JavaTypeMapping idParamMapping = new PersistableIdMapping((PersistableMapping) idMapping);
SQLExpression fieldExpr = exprFactory.newExpression(sqlStmtMain, sqlStmtMain.getPrimaryTable(), idMapping);
SQLExpression fieldVal = exprFactory.newLiteralParameter(sqlStmtMain, idParamMapping, id, "ID");
sqlStmtMain.whereAnd(fieldExpr.eq(fieldVal), true);
} else {
SelectStatement sqlStmt = stmtGen.getStatement(ec);
// WHERE (object id) = ?
JavaTypeMapping idMapping = sqlStmt.getPrimaryTable().getTable().getIdMapping();
JavaTypeMapping idParamMapping = new PersistableIdMapping((PersistableMapping) idMapping);
SQLExpression fieldExpr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), idMapping);
SQLExpression fieldVal = exprFactory.newLiteralParameter(sqlStmt, idParamMapping, id, "ID");
sqlStmt.whereAnd(fieldExpr.eq(fieldVal), true);
sqlStmtMain.union(sqlStmt);
}
}
}
// Perform the query
if (sqlStmtMain != null) {
try {
ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
SQLController sqlControl = storeMgr.getSQLController();
if (sampleCmd != null && ec.getSerializeReadForClass(sampleCmd.getFullClassName())) {
sqlStmtMain.addExtension(SQLStatement.EXTENSION_LOCK_FOR_UPDATE, true);
}
try {
PreparedStatement ps = SQLStatementHelper.getPreparedStatementForSQLStatement(sqlStmtMain, ec, mconn, null, null);
String statement = sqlStmtMain.getSQLText().toSQL();
try {
ResultSet rs = sqlControl.executeStatementQuery(ec, mconn, statement, ps);
try {
while (rs.next()) {
try {
return rs.getString(UnionStatementGenerator.DN_TYPE_COLUMN).trim();
} catch (SQLException sqle) {
}
}
} finally {
rs.close();
}
} finally {
sqlControl.closeStatement(mconn, ps);
}
} finally {
mconn.release();
}
} catch (SQLException sqe) {
NucleusLogger.DATASTORE.error("Exception with UNION statement", sqe);
throw new NucleusDataStoreException(sqe.toString());
}
}
return null;
}
Aggregations