Search in sources :

Example 6 with Column

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;
}
Also used : NucleusDataStoreException(org.datanucleus.exceptions.NucleusDataStoreException) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) Column(org.datanucleus.store.rdbms.table.Column) ResultSet(java.sql.ResultSet) PreparedStatement(java.sql.PreparedStatement) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager)

Example 7 with Column

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);
    }
}
Also used : ElementMetaData(org.datanucleus.metadata.ElementMetaData) KeyMetaData(org.datanucleus.metadata.KeyMetaData) Column(org.datanucleus.store.rdbms.table.Column) ValueMetaData(org.datanucleus.metadata.ValueMetaData) ColumnMetaData(org.datanucleus.metadata.ColumnMetaData) MappingManager(org.datanucleus.store.rdbms.mapping.MappingManager) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData)

Example 8 with Column

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;
}
Also used : Column(org.datanucleus.store.rdbms.table.Column) NucleusObjectNotFoundException(org.datanucleus.exceptions.NucleusObjectNotFoundException) NullValueException(org.datanucleus.store.rdbms.exceptions.NullValueException)

Example 9 with Column

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);
}
Also used : Column(org.datanucleus.store.rdbms.table.Column) MappingManager(org.datanucleus.store.rdbms.mapping.MappingManager) ColumnMetaData(org.datanucleus.metadata.ColumnMetaData)

Example 10 with Column

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);
}
Also used : Column(org.datanucleus.store.rdbms.table.Column) MappingManager(org.datanucleus.store.rdbms.mapping.MappingManager) ColumnMetaData(org.datanucleus.metadata.ColumnMetaData)

Aggregations

Column (org.datanucleus.store.rdbms.table.Column)24 MappingManager (org.datanucleus.store.rdbms.mapping.MappingManager)10 ColumnMetaData (org.datanucleus.metadata.ColumnMetaData)8 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)5 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)5 IdentifierFactory (org.datanucleus.store.rdbms.identifier.IdentifierFactory)5 DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)4 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)3 DatastoreIdentifier (org.datanucleus.store.rdbms.identifier.DatastoreIdentifier)3 DatastoreMapping (org.datanucleus.store.rdbms.mapping.datastore.DatastoreMapping)3 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)3 ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)2 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)2 ForeignKey (org.datanucleus.store.rdbms.key.ForeignKey)2 PrimaryKey (org.datanucleus.store.rdbms.key.PrimaryKey)2 Table (org.datanucleus.store.rdbms.table.Table)2 Constructor (java.lang.reflect.Constructor)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 PreparedStatement (java.sql.PreparedStatement)1 ResultSet (java.sql.ResultSet)1