Search in sources :

Example 1 with AbstractClassMetaData

use of org.datanucleus.metadata.AbstractClassMetaData in project datanucleus-rdbms by datanucleus.

the class MappingManagerImpl method getMapping.

/**
 * Accessor for the mapping for the member of the specified table.
 * Can be used for members of a class, element of a collection of a class, element of an array of a class,
 * keys of a map of a class, values of a map of a class; this is controlled by the role argument.
 * @param table Table to add the mapping to
 * @param mmd MetaData for the member to map
 * @param clr The ClassLoaderResolver
 * @param fieldRole Role that this mapping plays for the field
 * @return The mapping for the member.
 */
public JavaTypeMapping getMapping(Table table, AbstractMemberMetaData mmd, ClassLoaderResolver clr, FieldRole fieldRole) {
    if (fieldRole == FieldRole.ROLE_COLLECTION_ELEMENT || fieldRole == FieldRole.ROLE_ARRAY_ELEMENT) {
        // Mapping a collection/array element (in a join table)
        return getElementMapping(table, mmd, fieldRole, clr);
    } else if (fieldRole == FieldRole.ROLE_MAP_KEY) {
        // Mapping a map key (in a join table)
        return getKeyMapping(table, mmd, clr);
    } else if (fieldRole == FieldRole.ROLE_MAP_VALUE) {
        // Mapping a map value (in a join table)
        return getValueMapping(table, mmd, clr);
    }
    // Check for use of TypeConverter (either specific, or auto-apply for this type)
    TypeManager typeMgr = table.getStoreManager().getNucleusContext().getTypeManager();
    TypeConverter conv = null;
    if (!mmd.isTypeConversionDisabled()) {
        // User-specified TypeConverter defined for the whole member, or an autoApply is present for this member type
        if (mmd.getTypeConverterName() != null) {
            conv = typeMgr.getTypeConverterForName(mmd.getTypeConverterName());
            if (conv == null) {
                throw new NucleusUserException(Localiser.msg("044062", mmd.getFullFieldName(), mmd.getTypeConverterName()));
            }
        } else {
            TypeConverter autoApplyConv = typeMgr.getAutoApplyTypeConverterForType(mmd.getType());
            if (autoApplyConv != null) {
                conv = autoApplyConv;
            }
        }
        if (conv != null) {
            // Create the mapping of the selected type
            JavaTypeMapping m = null;
            if (conv instanceof MultiColumnConverter) {
                Class mc = TypeConverterMultiMapping.class;
                try {
                    m = (JavaTypeMapping) mc.newInstance();
                    m.setRoleForMember(FieldRole.ROLE_FIELD);
                    ((TypeConverterMultiMapping) m).initialize(mmd, table, clr, conv);
                    return m;
                } catch (Exception e) {
                    throw new NucleusException(Localiser.msg("041009", mc.getName(), e), e).setFatal();
                }
            }
            Class mc = TypeConverterMapping.class;
            try {
                m = (JavaTypeMapping) mc.newInstance();
                m.setRoleForMember(FieldRole.ROLE_FIELD);
                ((TypeConverterMapping) m).initialize(mmd, table, clr, conv);
                return m;
            } catch (Exception e) {
                throw new NucleusException(Localiser.msg("041009", mc.getName(), e), e).setFatal();
            }
        }
    }
    AbstractMemberMetaData overrideMmd = null;
    MappingConverterDetails mcd = null;
    Class mc = null;
    String userMappingClassName = mmd.getValueForExtension("mapping-class");
    if (userMappingClassName != null) {
        // User has defined their own mapping class for this field so use that
        try {
            mc = clr.classForName(userMappingClassName);
        } catch (NucleusException ne) {
            throw new NucleusUserException(Localiser.msg("041014", mmd.getFullFieldName(), userMappingClassName)).setFatal();
        }
    } else {
        AbstractClassMetaData typeCmd = null;
        if (mmd.getType().isInterface()) {
            typeCmd = storeMgr.getNucleusContext().getMetaDataManager().getMetaDataForInterface(mmd.getType(), clr);
        } else {
            typeCmd = storeMgr.getNucleusContext().getMetaDataManager().getMetaDataForClass(mmd.getType(), clr);
        }
        if (mmd.hasExtension(SerialisedLocalFileMapping.EXTENSION_SERIALIZE_TO_FOLDER) && Serializable.class.isAssignableFrom(mmd.getType())) {
            // Special case : use file serialization mapping
            mc = SerialisedLocalFileMapping.class;
        } else if (mmd.isSerialized()) {
            // Field is marked as serialised then we have no other option - serialise it
            mcd = getMappingClass(mmd.getType(), true, false, null, mmd.getFullFieldName());
        } else if (mmd.getEmbeddedMetaData() != null) {
            // Field has an <embedded> specification so use that
            mcd = getMappingClass(mmd.getType(), false, true, null, mmd.getFullFieldName());
        } else if (typeCmd != null && typeCmd.isEmbeddedOnly()) {
            // Reference type is declared with embedded only
            mcd = getMappingClass(mmd.getType(), false, true, null, mmd.getFullFieldName());
        } else if (// TODO Check this since it will push all basic nonPC fields through here
        mmd.isEmbedded()) {
            // Otherwise, if the field is embedded then we request that it be serialised into the owner table
            // This is particularly for java.lang.Object which should be "embedded" by default, and hence serialised
            mcd = getMappingClass(mmd.getType(), true, false, mmd.getColumnMetaData(), mmd.getFullFieldName());
        } else {
            // Non-embedded/non-serialised - Just get the basic mapping for the type
            Class memberType = mmd.getType();
            mcd = getMappingClass(memberType, false, false, mmd.getColumnMetaData(), mmd.getFullFieldName());
            if (mmd.getParent() instanceof EmbeddedMetaData && mmd.getRelationType(clr) != RelationType.NONE) {
                // See NUCCORE-697 - always need to use the real member metadata for the mapping
                // so that it can find sub-fields when persisting/querying etc
                AbstractClassMetaData cmdForFmd = table.getStoreManager().getMetaDataManager().getMetaDataForClass(mmd.getClassName(), clr);
                overrideMmd = cmdForFmd.getMetaDataForMember(mmd.getName());
            }
        }
    }
    // Create the mapping of the selected type
    if (mcd != null) {
        mc = mcd.mappingClass;
        // Allow override by Oracle
        mc = getOverrideMappingClass(mc, mmd, fieldRole);
    }
    if (mc != null && (mcd == null || mcd.typeConverter == null)) {
        try {
            JavaTypeMapping m = (JavaTypeMapping) mc.newInstance();
            m.setRoleForMember(FieldRole.ROLE_FIELD);
            m.initialize(mmd, table, clr);
            if (overrideMmd != null) {
                // Note cannot just use this overrideMmd in the initialize(...) call above, a test fails.
                m.setMemberMetaData(overrideMmd);
            }
            return m;
        } catch (Exception e) {
            throw new NucleusException(Localiser.msg("041009", mc.getName(), e), e).setFatal();
        }
    } else if (mcd != null && mcd.typeConverter != null) {
        try {
            JavaTypeMapping m = (JavaTypeMapping) mcd.mappingClass.newInstance();
            m.setRoleForMember(FieldRole.ROLE_FIELD);
            if (m instanceof TypeConverterMapping) {
                ((TypeConverterMapping) m).initialize(mmd, table, clr, mcd.typeConverter);
            } else if (m instanceof TypeConverterMultiMapping) {
                ((TypeConverterMultiMapping) m).initialize(mmd, table, clr, mcd.typeConverter);
            }
            if (overrideMmd != null) {
                // Note cannot just use this overrideMmd in the initialize(...) call above, a test fails.
                m.setMemberMetaData(overrideMmd);
            }
            return m;
        } catch (Exception e) {
            throw new NucleusException(Localiser.msg("041009", mc.getName(), e), e).setFatal();
        }
    }
    throw new NucleusException("Unable to create mapping for member at " + mmd.getFullFieldName() + " - no available mapping");
}
Also used : Serializable(java.io.Serializable) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) EmbeddedMetaData(org.datanucleus.metadata.EmbeddedMetaData) MultiColumnConverter(org.datanucleus.store.types.converters.MultiColumnConverter) NucleusException(org.datanucleus.exceptions.NucleusException) NoTableManagedException(org.datanucleus.store.rdbms.exceptions.NoTableManagedException) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) TypeConverter(org.datanucleus.store.types.converters.TypeConverter) TypeConverterMapping(org.datanucleus.store.rdbms.mapping.java.TypeConverterMapping) TypeManager(org.datanucleus.store.types.TypeManager) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) NucleusException(org.datanucleus.exceptions.NucleusException) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) TypeConverterMultiMapping(org.datanucleus.store.rdbms.mapping.java.TypeConverterMultiMapping)

Example 2 with AbstractClassMetaData

use of org.datanucleus.metadata.AbstractClassMetaData in project datanucleus-rdbms by datanucleus.

the class OracleClobRDBMSMapping method updateClobColumn.

/**
 * Convenience method to update the contents of a CLOB column.
 * Oracle requires that a CLOB is initialised with EMPTY_CLOB() and then you retrieve
 * the column and update its CLOB value. Performs a statement
 * <pre>
 * SELECT {clobColumn} FROM TABLE WHERE ID=? FOR UPDATE
 * </pre>
 * and then updates the Clob value returned.
 * @param op ObjectProvider of the object
 * @param table Table storing the CLOB column
 * @param mapping Datastore mapping for the CLOB column
 * @param value The value to store in the CLOB
 * @throws NucleusObjectNotFoundException Thrown if an object is not found
 * @throws NucleusDataStoreException Thrown if an error occurs in datastore communication
 */
@SuppressWarnings("deprecation")
public static void updateClobColumn(ObjectProvider op, Table table, DatastoreMapping mapping, String value) {
    ExecutionContext ec = op.getExecutionContext();
    RDBMSStoreManager storeMgr = table.getStoreManager();
    // Don't support join tables yet
    DatastoreClass classTable = (DatastoreClass) table;
    SQLExpressionFactory exprFactory = storeMgr.getSQLExpressionFactory();
    // Generate "SELECT {clobColumn} 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 CLOB type
                        // we have to cast to that, face west, pray whilst saying ommmmmmmmmmm
                        oracle.sql.CLOB clob = (oracle.sql.CLOB) rs.getClob(1);
                        if (clob != null) {
                            // Deprecated but what can you do
                            clob.putString(1, value);
                        }
                    } else {
                        // Oracle JDBC drivers 10 and above supposedly use the JDBC standard class for Clobs
                        java.sql.Clob clob = rs.getClob(1);
                        if (clob != null) {
                            clob.setString(1, value);
                        }
                    }
                } finally {
                    rs.close();
                }
            } finally {
                sqlControl.closeStatement(mconn, ps);
            }
        } finally {
            mconn.release();
        }
    } catch (SQLException e) {
        throw new NucleusDataStoreException("Update of CLOB value failed: " + textStmt, e);
    }
}
Also used : SQLExpressionFactory(org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) SQLException(java.sql.SQLException) StatementMappingIndex(org.datanucleus.store.rdbms.query.StatementMappingIndex) ParameterSetter(org.datanucleus.store.rdbms.fieldmanager.ParameterSetter) NucleusObjectNotFoundException(org.datanucleus.exceptions.NucleusObjectNotFoundException) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) SQLController(org.datanucleus.store.rdbms.SQLController) SelectStatement(org.datanucleus.store.rdbms.sql.SelectStatement) NucleusDataStoreException(org.datanucleus.exceptions.NucleusDataStoreException) SQLTable(org.datanucleus.store.rdbms.sql.SQLTable) ResultSet(java.sql.ResultSet) ManagedConnection(org.datanucleus.store.connection.ManagedConnection) PreparedStatement(java.sql.PreparedStatement) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) StatementClassMapping(org.datanucleus.store.rdbms.query.StatementClassMapping) ExecutionContext(org.datanucleus.ExecutionContext) ObjectProvider(org.datanucleus.state.ObjectProvider) DatastoreAdapter(org.datanucleus.store.rdbms.adapter.DatastoreAdapter) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Example 3 with AbstractClassMetaData

use of org.datanucleus.metadata.AbstractClassMetaData in project datanucleus-rdbms by datanucleus.

the class EmbeddedMapping method initialize.

/**
 * Initialize for the specified member.
 * @param mmd metadata for the embedded member
 * @param table Table for persisting this field
 * @param clr The ClassLoaderResolver
 * @param emd Embedded MetaData for the object being embedded
 * @param typeName type of the embedded PC object being stored
 * @param objectType Object type of the PC object being embedded (see StateManagerImpl object types)
 */
public void initialize(AbstractMemberMetaData mmd, Table table, ClassLoaderResolver clr, EmbeddedMetaData emd, String typeName, int objectType) {
    super.initialize(mmd, table, clr);
    this.clr = clr;
    this.emd = emd;
    this.typeName = typeName;
    this.objectType = (short) objectType;
    // Find the MetaData for the embedded PC class
    MetaDataManager mmgr = table.getStoreManager().getMetaDataManager();
    AbstractClassMetaData rootEmbCmd = mmgr.getMetaDataForClass(typeName, clr);
    if (rootEmbCmd == null) {
        // Not found so must be an interface
        // Try using the fieldTypes on the field/property - we support it if only 1 implementation
        String[] fieldTypes = mmd.getFieldTypes();
        if (fieldTypes != null && fieldTypes.length == 1) {
            rootEmbCmd = mmgr.getMetaDataForClass(fieldTypes[0], clr);
        } else if (fieldTypes != null && fieldTypes.length > 1) {
            // TODO Cater for multiple implementations
            throw new NucleusUserException("Field " + mmd.getFullFieldName() + " is a reference field that is embedded with multiple possible implementations. " + "DataNucleus doesnt support embedded reference fields that have more than 1 implementation");
        }
        if (rootEmbCmd == null) {
            // Try a persistent interface
            rootEmbCmd = mmgr.getMetaDataForInterface(clr.classForName(typeName), clr);
            if (rootEmbCmd == null && mmd.getFieldTypes() != null && mmd.getFieldTypes().length == 1) {
                // No MetaData for the type so try "fieldType" specified on the field
                rootEmbCmd = mmgr.getMetaDataForInterface(clr.classForName(mmd.getFieldTypes()[0]), clr);
            }
        }
    }
    if (rootEmbCmd == null) {
        throw new NucleusUserException("Unable to find root class embedded metadata for field=" + mmd.getFullFieldName());
    }
    embCmd = rootEmbCmd;
    AbstractMemberMetaData[] embFmds = null;
    if (emd == null && rootEmbCmd.isEmbeddedOnly()) {
        // No <embedded> block yet the class is defined as embedded-only so just use its own definition of fields
        embFmds = rootEmbCmd.getManagedMembers();
    } else if (emd != null) {
        // <embedded> block so use those field definitions
        embFmds = emd.getMemberMetaData();
    }
    String[] subclasses = mmgr.getSubclassesForClass(rootEmbCmd.getFullClassName(), true);
    if (subclasses != null && subclasses.length > 0) {
        if (rootEmbCmd.hasDiscriminatorStrategy()) {
            // Fabricate a DiscriminatorMetaData to use for the embedded object
            discrimMetaData = new DiscriminatorMetaData();
            InheritanceMetaData embInhMd = new InheritanceMetaData();
            embInhMd.setParent(rootEmbCmd);
            discrimMetaData.setParent(embInhMd);
            // Set strategy based on the inheritance of the embedded object, otherwise class name.
            DiscriminatorMetaData dismd = rootEmbCmd.getDiscriminatorMetaDataRoot();
            if (dismd.getStrategy() != null && dismd.getStrategy() != DiscriminatorStrategy.NONE) {
                discrimMetaData.setStrategy(dismd.getStrategy());
            } else {
                // Fallback to class name
                discrimMetaData.setStrategy(DiscriminatorStrategy.CLASS_NAME);
            }
            // Set column for discriminator
            ColumnMetaData disColmd = new ColumnMetaData();
            disColmd.setAllowsNull(Boolean.TRUE);
            DiscriminatorMetaData embDismd = (emd != null) ? emd.getDiscriminatorMetaData() : null;
            if (embDismd != null && embDismd.getColumnMetaData() != null) {
                disColmd.setName(embDismd.getColumnMetaData().getName());
            } else {
                ColumnMetaData colmd = dismd.getColumnMetaData();
                if (colmd != null && colmd.getName() != null) {
                    disColmd.setName(colmd.getName());
                }
            }
            discrimMetaData.setColumnMetaData(disColmd);
            discrimMapping = DiscriminatorMapping.createDiscriminatorMapping(table, discrimMetaData);
            addDatastoreMapping(discrimMapping.getDatastoreMapping(0));
        } else {
            NucleusLogger.PERSISTENCE.info("Member " + mmd.getFullFieldName() + " is embedded and the type " + "(" + rootEmbCmd.getFullClassName() + ") has potential subclasses." + " Impossible to detect which is stored embedded. Add a discriminator to the embedded type");
        }
    }
    // Add all fields of the embedded class (that are persistent)
    int[] pcFieldNumbers = rootEmbCmd.getAllMemberPositions();
    for (int i = 0; i < pcFieldNumbers.length; i++) {
        AbstractMemberMetaData rootEmbMmd = rootEmbCmd.getMetaDataForManagedMemberAtAbsolutePosition(pcFieldNumbers[i]);
        if (rootEmbMmd.getPersistenceModifier() == FieldPersistenceModifier.PERSISTENT) {
            addMappingForMember(rootEmbCmd, rootEmbMmd, embFmds);
        }
    }
    // Add fields for any subtypes (that are persistent)
    if (discrimMapping != null && subclasses != null && subclasses.length > 0) {
        for (int i = 0; i < subclasses.length; i++) {
            AbstractClassMetaData subEmbCmd = storeMgr.getMetaDataManager().getMetaDataForClass(subclasses[i], clr);
            AbstractMemberMetaData[] subEmbMmds = subEmbCmd.getManagedMembers();
            if (subEmbMmds != null) {
                for (int j = 0; j < subEmbMmds.length; j++) {
                    if (subEmbMmds[j].getPersistenceModifier() == FieldPersistenceModifier.PERSISTENT) {
                        addMappingForMember(subEmbCmd, subEmbMmds[j], embFmds);
                    }
                }
            }
        }
    }
}
Also used : DiscriminatorMetaData(org.datanucleus.metadata.DiscriminatorMetaData) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) MetaDataManager(org.datanucleus.metadata.MetaDataManager) ColumnMetaData(org.datanucleus.metadata.ColumnMetaData) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) InheritanceMetaData(org.datanucleus.metadata.InheritanceMetaData) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData)

Example 4 with AbstractClassMetaData

use of org.datanucleus.metadata.AbstractClassMetaData in project datanucleus-rdbms by datanucleus.

the class ResultSetGetter method processSubObjectFields.

private Object processSubObjectFields(JavaTypeMapping mapping, Class fieldType, StatementClassMapping relationMappings) {
    ClassLoaderResolver clr = ec.getClassLoaderResolver();
    AbstractClassMetaData relatedCmd = ec.getMetaDataManager().getMetaDataForClass(fieldType, clr);
    if (mapping instanceof ReferenceMapping) {
        // Special case where we have a ReferenceMapping and single implementation with FK
        ReferenceMapping refMapping = (ReferenceMapping) mapping;
        if (refMapping.getMappingStrategy() == ReferenceMapping.PER_IMPLEMENTATION_MAPPING) {
            JavaTypeMapping[] subMappings = refMapping.getJavaTypeMapping();
            if (subMappings != null && subMappings.length == 1) {
                relatedCmd = ec.getMetaDataManager().getMetaDataForClass(subMappings[0].getType(), clr);
                fieldType = clr.classForName(subMappings[0].getType());
            }
        }
    }
    ResultObjectFactory relationROF = new PersistentClassROF(ec, rs, false, relationMappings, relatedCmd, fieldType);
    return relationROF.getObject();
}
Also used : SerialisedReferenceMapping(org.datanucleus.store.rdbms.mapping.java.SerialisedReferenceMapping) ReferenceMapping(org.datanucleus.store.rdbms.mapping.java.ReferenceMapping) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) PersistentClassROF(org.datanucleus.store.rdbms.query.PersistentClassROF) ResultObjectFactory(org.datanucleus.store.rdbms.query.ResultObjectFactory) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData)

Example 5 with AbstractClassMetaData

use of org.datanucleus.metadata.AbstractClassMetaData in project datanucleus-rdbms by datanucleus.

the class DNIdentifierFactory method newTableIdentifier.

/**
 * Method to return a Table identifier for the join table of the specified field.
 * @param mmd Meta data for the field
 * @return The identifier for the table
 */
public DatastoreIdentifier newTableIdentifier(AbstractMemberMetaData mmd) {
    String identifierName = null;
    String schemaName = null;
    String catalogName = null;
    AbstractMemberMetaData[] relatedMmds = null;
    if (mmd.getColumnMetaData().length > 0 && mmd.getColumnMetaData()[0].getName() != null) {
        // Name the table based on the column
        identifierName = mmd.getColumnMetaData()[0].getName();
    } else if (mmd.hasContainer()) {
        // Check for a specified join table name
        if (mmd.getTable() != null) {
            // Join table name specified at this side
            String specifiedName = mmd.getTable();
            String[] parts = getIdentifierNamePartsFromName(specifiedName);
            if (parts != null) {
                catalogName = parts[0];
                schemaName = parts[1];
                identifierName = parts[2];
            }
            if (catalogName == null) {
                catalogName = mmd.getCatalog();
            }
            if (schemaName == null) {
                schemaName = mmd.getSchema();
            }
        } else {
            relatedMmds = mmd.getRelatedMemberMetaData(clr);
            if (relatedMmds != null && relatedMmds[0].getTable() != null) {
                // Join table name specified at other side (1-N or M-N)
                String specifiedName = relatedMmds[0].getTable();
                String[] parts = getIdentifierNamePartsFromName(specifiedName);
                if (parts != null) {
                    catalogName = parts[0];
                    schemaName = parts[1];
                    identifierName = parts[2];
                }
                if (catalogName == null) {
                    catalogName = mmd.getCatalog();
                }
                if (schemaName == null) {
                    schemaName = mmd.getSchema();
                }
            }
        }
    } else {
        // Check for a specified join table name (1-1/N-1 UNI join table case)
        if (mmd.getTable() != null) {
            // Join table name specified at this side
            String specifiedName = mmd.getTable();
            String[] parts = getIdentifierNamePartsFromName(specifiedName);
            if (parts != null) {
                catalogName = parts[0];
                schemaName = parts[1];
                identifierName = parts[2];
            }
            if (catalogName == null) {
                catalogName = mmd.getCatalog();
            }
            if (schemaName == null) {
                schemaName = mmd.getSchema();
            }
        }
    }
    // Note that we treat these as pairs (they both come from the same source)
    if (schemaName == null && catalogName == null) {
        // Check the <class schema="..." catalog="..." >
        if (mmd.getParent() instanceof AbstractClassMetaData) {
            AbstractClassMetaData ownerCmd = (AbstractClassMetaData) mmd.getParent();
            if (dba.supportsOption(DatastoreAdapter.CATALOGS_IN_TABLE_DEFINITIONS)) {
                catalogName = ownerCmd.getCatalog();
            }
            if (dba.supportsOption(DatastoreAdapter.SCHEMAS_IN_TABLE_DEFINITIONS)) {
                schemaName = ownerCmd.getSchema();
            }
        }
        if (schemaName == null && catalogName == null) {
            // Still no values, so try the PMF settings.
            if (dba.supportsOption(DatastoreAdapter.CATALOGS_IN_TABLE_DEFINITIONS)) {
                catalogName = this.defaultCatalogName;
            }
            if (dba.supportsOption(DatastoreAdapter.SCHEMAS_IN_TABLE_DEFINITIONS)) {
                schemaName = this.defaultSchemaName;
            }
        }
    }
    if (catalogName != null) {
        catalogName = getIdentifierInAdapterCase(catalogName);
    }
    if (schemaName != null) {
        schemaName = getIdentifierInAdapterCase(schemaName);
    }
    // No user-specified name, so generate a default using the previously created fallback
    if (identifierName == null) {
        // Use this field as the basis for the fallback name (CLASS_FIELD) unless
        // this is a bidirectional and the other side is the owner (has mapped-by) in which case OTHERCLASS_FIELD
        String fieldNameBasis = mmd.getFullFieldName();
        if (relatedMmds != null && relatedMmds[0].getMappedBy() != null) {
            // Other field has mapped-by so use that
            fieldNameBasis = relatedMmds[0].getFullFieldName();
        }
        // Generate a fallback name, based on the class/field name (CLASS_FIELD)
        ArrayList name_parts = new ArrayList();
        StringTokenizer tokens = new StringTokenizer(fieldNameBasis, ".");
        while (tokens.hasMoreTokens()) {
            name_parts.add(tokens.nextToken());
        }
        ListIterator li = name_parts.listIterator(name_parts.size());
        String unique_name = (String) li.previous();
        String full_name = (li.hasPrevious() ? (li.previous() + getWordSeparator()) : "") + unique_name;
        identifierName = "";
        if (tablePrefix != null && tablePrefix.length() > 0) {
            identifierName = tablePrefix;
        }
        identifierName += full_name;
        if (tableSuffix != null && tableSuffix.length() > 0) {
            identifierName += tableSuffix;
        }
    }
    // Generate the table identifier now that we have the identifier name
    DatastoreIdentifier identifier = newTableIdentifier(identifierName, catalogName, schemaName);
    return identifier;
}
Also used : StringTokenizer(java.util.StringTokenizer) ArrayList(java.util.ArrayList) ListIterator(java.util.ListIterator) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData)

Aggregations

AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)204 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)90 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)69 ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)59 DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)55 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)42 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)42 NucleusException (org.datanucleus.exceptions.NucleusException)37 MetaDataManager (org.datanucleus.metadata.MetaDataManager)37 ArrayList (java.util.ArrayList)31 SQLExpression (org.datanucleus.store.rdbms.sql.expression.SQLExpression)26 SQLTable (org.datanucleus.store.rdbms.sql.SQLTable)23 SQLExpressionFactory (org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory)22 ClassLoaderResolverImpl (org.datanucleus.ClassLoaderResolverImpl)19 MapTable (org.datanucleus.store.rdbms.table.MapTable)18 List (java.util.List)16 ObjectProvider (org.datanucleus.state.ObjectProvider)16 PersistableMapping (org.datanucleus.store.rdbms.mapping.java.PersistableMapping)16 SelectStatement (org.datanucleus.store.rdbms.sql.SelectStatement)16 Iterator (java.util.Iterator)15