use of org.datanucleus.store.rdbms.table.Column in project datanucleus-rdbms by datanucleus.
the class InsertRequest method getInsertedDatastoreIdentity.
/**
* Method to obtain the identity attributed by the datastore when using auto-increment/IDENTITY/SERIAL.
* @param ec execution context
* @param sqlControl SQLController
* @param op ObjectProvider of the object
* @param mconn The Connection
* @param ps PreparedStatement for the INSERT
* @return The identity
* @throws SQLException Thrown if an error occurs retrieving the identity
*/
private Object getInsertedDatastoreIdentity(ExecutionContext ec, SQLController sqlControl, ObjectProvider op, ManagedConnection mconn, PreparedStatement ps) throws SQLException {
Object datastoreId = null;
RDBMSStoreManager storeMgr = table.getStoreManager();
if (storeMgr.getDatastoreAdapter().supportsOption(DatastoreAdapter.GET_GENERATED_KEYS_STATEMENT)) {
// Try getGeneratedKeys() method to avoid extra SQL calls (only in more recent JDBC drivers)
ResultSet rs = null;
try {
rs = ps.getGeneratedKeys();
if (rs != null && rs.next()) {
datastoreId = rs.getObject(1);
}
} catch (Throwable e) {
// Not supported maybe (e.g HSQL), or the driver is too old
} finally {
if (rs != null) {
rs.close();
}
}
}
if (datastoreId == null) {
// Not found, so try the native method for retrieving it
String columnName = null;
JavaTypeMapping idMapping = table.getIdMapping();
if (idMapping != null) {
for (int i = 0; i < idMapping.getNumberOfDatastoreMappings(); i++) {
Column col = idMapping.getDatastoreMapping(i).getColumn();
if (col.isIdentity()) {
columnName = col.getIdentifier().toString();
break;
}
}
}
String autoIncStmt = storeMgr.getDatastoreAdapter().getAutoIncrementStmt(table, columnName);
PreparedStatement psAutoIncrement = sqlControl.getStatementForQuery(mconn, autoIncStmt);
ResultSet rs = null;
try {
rs = sqlControl.executeStatementQuery(ec, mconn, autoIncStmt, psAutoIncrement);
if (rs.next()) {
datastoreId = rs.getObject(1);
}
} finally {
if (rs != null) {
rs.close();
}
if (psAutoIncrement != null) {
psAutoIncrement.close();
}
}
}
if (datastoreId == null) {
throw new NucleusDataStoreException(Localiser.msg("052205", this.table));
}
return datastoreId;
}
use of org.datanucleus.store.rdbms.table.Column in project datanucleus-rdbms by datanucleus.
the class ReferenceMapping method prepareDatastoreMapping.
/**
* Convenience method to create the necessary columns to represent this reference in the datastore.
* With "per-implementation" mapping strategy will create columns for each of the possible implementations.
* With "identity"/"xcalia" will create a single column to store a reference to the implementation value.
* @param clr The ClassLoaderResolver
*/
protected void prepareDatastoreMapping(ClassLoaderResolver clr) {
if (mappingStrategy == PER_IMPLEMENTATION_MAPPING) {
// Mapping per reference implementation, so create columns for each possible implementation
if (roleForMember == FieldRole.ROLE_ARRAY_ELEMENT) {
// Creation of columns in join table for array of references
ColumnMetaData[] colmds = null;
ElementMetaData elemmd = mmd.getElementMetaData();
if (elemmd != null && elemmd.getColumnMetaData() != null && elemmd.getColumnMetaData().length > 0) {
// Column mappings defined at this side (1-N, M-N)
colmds = elemmd.getColumnMetaData();
}
createPerImplementationColumnsForReferenceField(false, false, false, false, roleForMember, colmds, clr);
} else if (roleForMember == FieldRole.ROLE_COLLECTION_ELEMENT) {
// Creation of columns in join table for collection of references
ColumnMetaData[] colmds = null;
AbstractMemberMetaData[] relatedMmds = mmd.getRelatedMemberMetaData(clr);
ElementMetaData elemmd = mmd.getElementMetaData();
if (elemmd != null && elemmd.getColumnMetaData() != null && elemmd.getColumnMetaData().length > 0) {
// Column mappings defined at this side (1-N, M-N)
colmds = elemmd.getColumnMetaData();
} else if (relatedMmds != null && relatedMmds[0].getJoinMetaData() != null && relatedMmds[0].getJoinMetaData().getColumnMetaData() != null && relatedMmds[0].getJoinMetaData().getColumnMetaData().length > 0) {
// Column mappings defined at other side (M-N) on <join>
colmds = relatedMmds[0].getJoinMetaData().getColumnMetaData();
}
createPerImplementationColumnsForReferenceField(false, false, false, false, roleForMember, colmds, clr);
} else if (roleForMember == FieldRole.ROLE_MAP_KEY) {
// Creation of columns in join table for map of references as keys
ColumnMetaData[] colmds = null;
KeyMetaData keymd = mmd.getKeyMetaData();
if (keymd != null && keymd.getColumnMetaData() != null && keymd.getColumnMetaData().length > 0) {
// Column mappings defined at this side (1-N, M-N)
colmds = keymd.getColumnMetaData();
}
createPerImplementationColumnsForReferenceField(false, false, false, false, roleForMember, colmds, clr);
} else if (roleForMember == FieldRole.ROLE_MAP_VALUE) {
// Creation of columns in join table for map of references as values
ColumnMetaData[] colmds = null;
ValueMetaData valuemd = mmd.getValueMetaData();
if (valuemd != null && valuemd.getColumnMetaData() != null && valuemd.getColumnMetaData().length > 0) {
// Column mappings defined at this side (1-N, M-N)
colmds = valuemd.getColumnMetaData();
}
createPerImplementationColumnsForReferenceField(false, false, false, false, roleForMember, colmds, clr);
} else {
if (mmd.getMappedBy() == null) {
// Unidirectional 1-1
boolean embedded = (mmd.isEmbedded() || mmd.getEmbeddedMetaData() != null);
createPerImplementationColumnsForReferenceField(false, true, false, embedded, roleForMember, mmd.getColumnMetaData(), clr);
} else {
// Bidirectional 1-1/N-1
AbstractClassMetaData refCmd = storeMgr.getNucleusContext().getMetaDataManager().getMetaDataForInterface(mmd.getType(), clr);
if (refCmd != null && refCmd.getInheritanceMetaData().getStrategy() == InheritanceStrategy.SUBCLASS_TABLE) {
// TODO Is this block actually reachable ? Would we specify "inheritance" under "interface" elements?
// Find the actual tables storing the other end (can be multiple subclasses)
AbstractClassMetaData[] cmds = storeMgr.getClassesManagingTableForClass(refCmd, clr);
if (cmds != null && cmds.length > 0) {
if (cmds.length > 1) {
NucleusLogger.PERSISTENCE.warn("Field " + mmd.getFullFieldName() + " represents either a 1-1 relation, or a N-1 relation where the other end uses" + " \"subclass-table\" inheritance strategy and more than 1 subclasses with a table. " + "This is not fully supported currently");
}
} else {
// TODO Throw an exception ?
return;
}
// TODO We need a mapping for each of the possible subclass tables
/*JavaTypeMapping referenceMapping = */
storeMgr.getDatastoreClass(cmds[0].getFullClassName(), clr).getIdMapping();
} else {
String[] implTypes = MetaDataUtils.getInstance().getImplementationNamesForReferenceField(mmd, FieldRole.ROLE_FIELD, clr, storeMgr.getMetaDataManager());
for (int j = 0; j < implTypes.length; j++) {
JavaTypeMapping refMapping = storeMgr.getDatastoreClass(implTypes[j], clr).getIdMapping();
JavaTypeMapping mapping = storeMgr.getMappingManager().getMapping(clr.classForName(implTypes[j]));
mapping.setReferenceMapping(refMapping);
this.addJavaTypeMapping(mapping);
}
}
}
}
} else if (mappingStrategy == ID_MAPPING || mappingStrategy == XCALIA_MAPPING) {
// Single (String) column storing the identity of the related object
MappingManager mapMgr = storeMgr.getMappingManager();
JavaTypeMapping mapping = mapMgr.getMapping(String.class);
mapping.setMemberMetaData(mmd);
mapping.setTable(table);
mapping.setRoleForMember(roleForMember);
Column col = mapMgr.createColumn(mapping, String.class.getName(), 0);
mapMgr.createDatastoreMapping(mapping, mmd, 0, col);
this.addJavaTypeMapping(mapping);
}
}
use of org.datanucleus.store.rdbms.table.Column in project datanucleus-rdbms by datanucleus.
the class MultiPersistableMapping method getObject.
/**
* Method to retrieve an object of this type from the ResultSet.
* @param ec execution context
* @param rs The ResultSet
* @param pos The parameter positions
* @return The object
*/
public Object getObject(ExecutionContext ec, final ResultSet rs, int[] pos) {
// Go through the possible types for this field and find a non-null value (if there is one)
int n = 0;
for (int i = 0; i < javaTypeMappings.length; i++) {
int[] posMapping;
if (n >= pos.length) {
// this means we store all implementations to the same columns, so we reset the index
n = 0;
}
if (javaTypeMappings[i].getReferenceMapping() != null) {
posMapping = new int[javaTypeMappings[i].getReferenceMapping().getNumberOfDatastoreMappings()];
} else {
posMapping = new int[javaTypeMappings[i].getNumberOfDatastoreMappings()];
}
for (int j = 0; j < posMapping.length; j++) {
posMapping[j] = pos[n++];
}
Object value = null;
try {
// Retrieve the value (PC object) for this mappings' object
value = javaTypeMappings[i].getObject(ec, rs, posMapping);
if (value != null) {
if (IdentityUtils.isDatastoreIdentity(value)) {
// What situation is this catering for exactly ?
Column col = null;
if (javaTypeMappings[i].getReferenceMapping() != null) {
col = javaTypeMappings[i].getReferenceMapping().getDatastoreMapping(0).getColumn();
} else {
col = javaTypeMappings[i].getDatastoreMapping(0).getColumn();
}
String className = col.getStoredJavaType();
value = ec.getNucleusContext().getIdentityManager().getDatastoreId(className, IdentityUtils.getTargetKeyForDatastoreIdentity(value));
return ec.findObject(value, false, true, null);
} else if (ec.getClassLoaderResolver().classForName(getType()).isAssignableFrom(value.getClass())) {
return value;
}
}
} catch (NullValueException e) {
// expected if implementation object is null and has primitive fields in the primary key
} catch (NucleusObjectNotFoundException onfe) {
// expected, will try next implementation
}
}
return null;
}
use of org.datanucleus.store.rdbms.table.Column in project datanucleus-rdbms by datanucleus.
the class SerialisedKeyPCMapping method prepareDatastoreMapping.
/**
* Method to prepare a field mapping for use in the datastore.
* This creates the column in the table.
*/
protected void prepareDatastoreMapping() {
MappingManager mmgr = storeMgr.getMappingManager();
ColumnMetaData colmd = null;
if (mmd.getKeyMetaData() != null && mmd.getKeyMetaData().getColumnMetaData() != null && mmd.getKeyMetaData().getColumnMetaData().length > 0) {
colmd = mmd.getKeyMetaData().getColumnMetaData()[0];
}
Column col = mmgr.createColumn(this, getType(), colmd);
mmgr.createDatastoreMapping(this, mmd, 0, col);
}
use of org.datanucleus.store.rdbms.table.Column in project datanucleus-rdbms by datanucleus.
the class SerialisedValuePCMapping method prepareDatastoreMapping.
/**
* Method to prepare a field mapping for use in the datastore.
* This creates the column in the table.
*/
protected void prepareDatastoreMapping() {
MappingManager mmgr = storeMgr.getMappingManager();
ColumnMetaData colmd = null;
if (mmd.getValueMetaData() != null && mmd.getValueMetaData().getColumnMetaData() != null && mmd.getValueMetaData().getColumnMetaData().length > 0) {
colmd = mmd.getValueMetaData().getColumnMetaData()[0];
}
Column col = mmgr.createColumn(this, getType(), colmd);
mmgr.createDatastoreMapping(this, mmd, 0, col);
}
Aggregations