Search in sources :

Example 21 with ClassLoaderResolver

use of org.datanucleus.ClassLoaderResolver in project datanucleus-rdbms by datanucleus.

the class PersistableMapping method preDelete.

/**
 * Method executed just before the owning object is deleted, allowing tidying up of any relation information.
 * @param sm StateManager for the owner
 */
public void preDelete(DNStateManager sm) {
    int fieldNumber = mmd.getAbsoluteFieldNumber();
    ExecutionContext ec = sm.getExecutionContext();
    ClassLoaderResolver clr = ec.getClassLoaderResolver();
    RelationType relationType = mmd.getRelationType(clr);
    AbstractMemberMetaData[] relatedMmds = mmd.getRelatedMemberMetaData(clr);
    // Check if we should delete the related object when this object is deleted
    boolean dependent = mmd.isDependent();
    if (mmd.isCascadeRemoveOrphans()) {
        // JPA allows "orphan removal" to define deletion of the other side
        dependent = true;
    }
    if (!dependent) {
        if (relationType == RelationType.ONE_TO_ONE_UNI) {
            // Special case of FK this side and unidirectional, just return
            return;
        }
    // TODO If we have the FK and not dependent then should avoid the load on the related object
    }
    if (!sm.isFieldLoaded(fieldNumber)) {
        // Load the field if we need its value
        try {
            // First try from stored FK value, otherwise load from database
            if (!sm.loadStoredField(fieldNumber)) {
                sm.loadField(fieldNumber);
            }
        } catch (NucleusObjectNotFoundException onfe) {
            // Already deleted so just return
            return;
        }
    }
    Object pc = sm.provideField(fieldNumber);
    pc = mmd.isSingleCollection() ? SCOUtils.singleCollectionValue(getStoreManager().getNucleusContext().getTypeManager(), pc) : pc;
    if (pc == null) {
        // Null value so nothing to do
        return;
    }
    // N-1 Uni, so delete join table entry
    if (relationType == RelationType.MANY_TO_ONE_UNI) {
        // Update join table entry
        PersistableRelationStore store = (PersistableRelationStore) storeMgr.getBackingStoreForField(clr, mmd, mmd.getType());
        store.remove(sm);
    }
    // Check if the field has a FK defined TODO Cater for more than 1 related field
    boolean hasFK = false;
    if (!dependent) {
        // Not dependent, so check if the datastore has a FK and will take care of it for us
        if (mmd.getForeignKeyMetaData() != null) {
            hasFK = true;
        }
        if (RelationType.isBidirectional(relationType) && relatedMmds[0].getForeignKeyMetaData() != null) {
            hasFK = true;
        }
        if (ec.getStringProperty(PropertyNames.PROPERTY_DELETION_POLICY).equals("JDO2")) {
            // JDO doesn't currently take note of foreign-key
            hasFK = false;
        }
    }
    // There may be some corner cases that this code doesn't yet cater for
    if (relationType == RelationType.ONE_TO_ONE_UNI || (relationType == RelationType.ONE_TO_ONE_BI && mmd.getMappedBy() == null)) {
        // 1-1 with FK at this side (owner of the relation)
        if (dependent) {
            boolean relatedObjectDeleted = ec.getApiAdapter().isDeleted(pc);
            if (isNullable() && !relatedObjectDeleted) {
                // Other object not yet deleted, but the field is nullable so just null out the FK
                // TODO Not doing this would cause errors in 1-1 uni relations (e.g AttachDetachTest)
                // TODO Log this since it affects the resultant objects
                sm.replaceFieldMakeDirty(fieldNumber, null);
                storeMgr.getPersistenceHandler().updateObject(sm, new int[] { fieldNumber });
                if (!relatedObjectDeleted) {
                    // Mark the other object for deletion since not yet tagged
                    ec.deleteObjectInternal(pc);
                }
            } else {
                // Can't just delete the other object since that would cause a FK constraint violation. Do nothing - handled by DeleteRequest on other object
                if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
                    NucleusLogger.DATASTORE_PERSIST.debug(Localiser.msg("041017", StringUtils.toJVMIDString(sm.getObject()), mmd.getFullFieldName()));
                }
            }
        } else {
            // We're deleting the FK at this side so shouldn't be an issue
            AbstractMemberMetaData relatedMmd = mmd.getRelatedMemberMetaDataForObject(clr, sm.getObject(), pc);
            if (relatedMmd != null) {
                DNStateManager otherSM = ec.findStateManager(pc);
                if (otherSM != null) {
                    // Managed Relations : 1-1 bidir, so null out the object at the other
                    Object currentValue = otherSM.provideField(relatedMmd.getAbsoluteFieldNumber());
                    if (currentValue != null) {
                        if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
                            NucleusLogger.PERSISTENCE.debug(Localiser.msg("041019", StringUtils.toJVMIDString(pc), relatedMmd.getFullFieldName(), sm.getObjectAsPrintable()));
                        }
                        otherSM.replaceFieldMakeDirty(relatedMmd.getAbsoluteFieldNumber(), null);
                        if (ec.getManageRelations()) {
                            otherSM.getExecutionContext().getRelationshipManager(otherSM).relationChange(relatedMmd.getAbsoluteFieldNumber(), sm.getObject(), null);
                        }
                    }
                }
            }
        }
    } else if (relationType == RelationType.ONE_TO_ONE_BI && mmd.getMappedBy() != null) {
        // 1-1 with FK at other side
        DatastoreClass relatedTable = storeMgr.getDatastoreClass(relatedMmds[0].getClassName(), clr);
        JavaTypeMapping relatedMapping = relatedTable.getMemberMapping(relatedMmds[0]);
        boolean isNullable = relatedMapping.isNullable();
        DNStateManager otherSM = ec.findStateManager(pc);
        if (dependent) {
            if (isNullable) {
                // Null out the FK in the datastore using a direct update (since we are deleting)
                otherSM.replaceFieldMakeDirty(relatedMmds[0].getAbsoluteFieldNumber(), null);
                storeMgr.getPersistenceHandler().updateObject(otherSM, new int[] { relatedMmds[0].getAbsoluteFieldNumber() });
            }
            // Mark the other object for deletion
            ec.deleteObjectInternal(pc);
        } else if (!hasFK) {
            if (isNullable()) {
                Object currentRelatedValue = otherSM.provideField(relatedMmds[0].getAbsoluteFieldNumber());
                if (currentRelatedValue != null) {
                    // Null out the FK in the datastore using a direct update (since we are deleting)
                    otherSM.replaceFieldMakeDirty(relatedMmds[0].getAbsoluteFieldNumber(), null);
                    storeMgr.getPersistenceHandler().updateObject(otherSM, new int[] { relatedMmds[0].getAbsoluteFieldNumber() });
                    // Managed Relations : 1-1 bidir, so null out the object at the other
                    if (ec.getManageRelations()) {
                        otherSM.getExecutionContext().getRelationshipManager(otherSM).relationChange(relatedMmds[0].getAbsoluteFieldNumber(), sm.getObject(), null);
                    }
                }
            } else {
            // TODO Remove it
            }
        } else {
        // User has a FK defined (in MetaData) so let the datastore take care of it
        }
    } else if (relationType == RelationType.MANY_TO_ONE_BI) {
        DNStateManager otherSM = ec.findStateManager(pc);
        if (relatedMmds[0].getJoinMetaData() == null) {
            // N-1 with FK at this side
            if (otherSM.isDeleting()) {
            // Other object is being deleted too but this side has the FK so just delete this object
            } else {
                // Other object is not being deleted so delete it if necessary
                if (dependent) {
                    if (isNullable()) {
                        // TODO Datastore nullability info can be unreliable so try to avoid this call
                        // Null out the FK in the datastore using a direct update (since we are deleting)
                        sm.replaceFieldMakeDirty(fieldNumber, null);
                        storeMgr.getPersistenceHandler().updateObject(sm, new int[] { fieldNumber });
                    }
                    if (ec.getApiAdapter().isDeleted(pc)) {
                    // Object is already tagged for deletion but we're deleting the FK so leave til flush()
                    } else {
                        // Mark the other object for deletion
                        ec.deleteObjectInternal(pc);
                    }
                } else {
                    // Managed Relations : remove element from collection/map
                    if (relatedMmds[0].hasCollection()) {
                        // Only update the other side if not already being deleted
                        if (!ec.getApiAdapter().isDeleted(otherSM.getObject()) && !otherSM.isDeleting()) {
                            // Make sure the other object is updated in any caches
                            ec.markDirty(otherSM, false);
                            // Make sure collection field is loaded
                            otherSM.isLoaded(relatedMmds[0].getAbsoluteFieldNumber());
                            Collection otherColl = (Collection) otherSM.provideField(relatedMmds[0].getAbsoluteFieldNumber());
                            if (otherColl != null) {
                                if (ec.getManageRelations()) {
                                    otherSM.getExecutionContext().getRelationshipManager(otherSM).relationRemove(relatedMmds[0].getAbsoluteFieldNumber(), sm.getObject());
                                }
                                if (otherColl.contains(sm.getObject())) {
                                    // TODO Localise this message
                                    NucleusLogger.PERSISTENCE.debug("ManagedRelationships : delete of object causes removal from collection at " + relatedMmds[0].getFullFieldName());
                                    otherColl.remove(sm.getObject());
                                }
                            }
                        }
                    } else if (relatedMmds[0].hasMap()) {
                    // TODO Cater for maps, but what is the key/value pair ?
                    }
                }
            }
        } else {
            // N-1 with join table so no FK here so need to remove from Collection/Map first? (managed relations)
            if (dependent) {
                // Mark the other object for deletion
                ec.deleteObjectInternal(pc);
            } else {
                // Managed Relations : remove element from collection/map
                if (relatedMmds[0].hasCollection()) {
                    // Only update the other side if not already being deleted
                    if (!ec.getApiAdapter().isDeleted(otherSM.getObject()) && !otherSM.isDeleting()) {
                        // Make sure the other object is updated in any caches
                        ec.markDirty(otherSM, false);
                        // Make sure the other object has the collection loaded so does this change
                        otherSM.isLoaded(relatedMmds[0].getAbsoluteFieldNumber());
                        Collection otherColl = (Collection) otherSM.provideField(relatedMmds[0].getAbsoluteFieldNumber());
                        if (otherColl != null && otherColl.contains(sm.getObject())) {
                            // TODO Localise this
                            NucleusLogger.PERSISTENCE.debug("ManagedRelationships : delete of object causes removal from collection at " + relatedMmds[0].getFullFieldName());
                            otherColl.remove(sm.getObject());
                        }
                    }
                } else if (relatedMmds[0].hasMap()) {
                // TODO Cater for maps, but what is the key/value pair ?
                }
            }
        }
    } else if (relationType == RelationType.MANY_TO_ONE_UNI) {
        // N-1 uni with join table
        if (dependent) {
            // Mark the other object for deletion
            ec.deleteObjectInternal(pc);
        }
    } else {
    // No relation so what is this field ?
    }
}
Also used : ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) NucleusObjectNotFoundException(org.datanucleus.exceptions.NucleusObjectNotFoundException) ExecutionContext(org.datanucleus.ExecutionContext) RelationType(org.datanucleus.metadata.RelationType) Collection(java.util.Collection) SCOCollection(org.datanucleus.store.types.SCOCollection) DNStateManager(org.datanucleus.state.DNStateManager) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) PersistableRelationStore(org.datanucleus.store.types.scostore.PersistableRelationStore)

Example 22 with ClassLoaderResolver

use of org.datanucleus.ClassLoaderResolver in project datanucleus-rdbms by datanucleus.

the class BulkFetchExistsHandler method getStatementToBulkFetchField.

/**
 * Convenience method to generate a bulk-fetch statement for the specified multi-valued field of the owning query.
 * @param candidateCmd Metadata for the candidate
 * @param parameters Parameters for the query
 * @param mmd Metadata for the multi-valued field
 * @param datastoreCompilation The datastore compilation of the query
 * @param mapperOptions Any options for the query to SQL mapper
 * @return The bulk-fetch statement for retrieving this multi-valued field.
 */
public IteratorStatement getStatementToBulkFetchField(AbstractClassMetaData candidateCmd, AbstractMemberMetaData mmd, Query query, Map parameters, RDBMSQueryCompilation datastoreCompilation, Set<String> mapperOptions) {
    IteratorStatement iterStmt = null;
    ExecutionContext ec = query.getExecutionContext();
    ClassLoaderResolver clr = ec.getClassLoaderResolver();
    RDBMSStoreManager storeMgr = (RDBMSStoreManager) query.getStoreManager();
    Store backingStore = storeMgr.getBackingStoreForField(clr, mmd, null);
    if (backingStore instanceof JoinSetStore || backingStore instanceof JoinListStore || backingStore instanceof JoinArrayStore) {
        // Set/List/array using join-table : Generate an iterator query of the form
        if (backingStore instanceof JoinSetStore) {
            iterStmt = ((JoinSetStore) backingStore).getIteratorStatement(ec, ec.getFetchPlan(), false);
        } else if (backingStore instanceof JoinListStore) {
            iterStmt = ((JoinListStore) backingStore).getIteratorStatement(ec, ec.getFetchPlan(), false, -1, -1);
        } else if (backingStore instanceof JoinArrayStore) {
            iterStmt = ((JoinArrayStore) backingStore).getIteratorStatement(ec, ec.getFetchPlan(), false);
        } else {
            throw new NucleusUserException("We do not support BulkFetch using EXISTS for backingStore = " + backingStore);
        }
        // SELECT ELEM_TBL.COL1, ELEM_TBL.COL2, ... FROM JOIN_TBL INNER_JOIN ELEM_TBL WHERE JOIN_TBL.ELEMENT_ID = ELEM_TBL.ID
        // AND EXISTS (SELECT OWNER_TBL.ID FROM OWNER_TBL WHERE (queryWhereClause) AND JOIN_TBL.OWNER_ID = OWNER_TBL.ID)
        SelectStatement sqlStmt = iterStmt.getSelectStatement();
        JoinTable joinTbl = (JoinTable) sqlStmt.getPrimaryTable().getTable();
        JavaTypeMapping joinOwnerMapping = joinTbl.getOwnerMapping();
        // Generate the EXISTS subquery (based on the JDOQL/JPQL query)
        SelectStatement existsStmt = RDBMSQueryUtils.getStatementForCandidates(storeMgr, sqlStmt, candidateCmd, datastoreCompilation.getResultDefinitionForClass(), ec, query.getCandidateClass(), query.isSubclasses(), query.getResult(), null, null, null);
        Set<String> options = new HashSet<>();
        if (mapperOptions != null) {
            options.addAll(mapperOptions);
        }
        options.add(QueryToSQLMapper.OPTION_SELECT_CANDIDATE_ID_ONLY);
        QueryToSQLMapper sqlMapper = new QueryToSQLMapper(existsStmt, query.getCompilation(), parameters, null, null, candidateCmd, query.isSubclasses(), query.getFetchPlan(), ec, query.getParsedImports(), options, query.getExtensions());
        sqlMapper.compile();
        // Add EXISTS clause on iterator statement so we can restrict to just the owners in this query
        // ORDER BY in EXISTS is forbidden by some RDBMS
        existsStmt.setOrdering(null, null);
        BooleanExpression existsExpr = new BooleanSubqueryExpression(sqlStmt, "EXISTS", existsStmt);
        sqlStmt.whereAnd(existsExpr, true);
        // Join to outer statement so we restrict to collection elements for the query candidates
        SQLExpression joinTblOwnerExpr = sqlStmt.getRDBMSManager().getSQLExpressionFactory().newExpression(sqlStmt, sqlStmt.getPrimaryTable(), joinOwnerMapping);
        SQLExpression existsOwnerExpr = sqlStmt.getRDBMSManager().getSQLExpressionFactory().newExpression(existsStmt, existsStmt.getPrimaryTable(), existsStmt.getPrimaryTable().getTable().getIdMapping());
        existsStmt.whereAnd(joinTblOwnerExpr.eq(existsOwnerExpr), true);
        // Select the owner candidate so we can separate the collection elements out to their owner
        int[] ownerColIndexes = sqlStmt.select(joinTblOwnerExpr, null);
        StatementMappingIndex ownerMapIdx = new StatementMappingIndex(existsStmt.getPrimaryTable().getTable().getIdMapping());
        ownerMapIdx.setColumnPositions(ownerColIndexes);
        iterStmt.setOwnerMapIndex(ownerMapIdx);
    } else if (backingStore instanceof FKSetStore || backingStore instanceof FKListStore || backingStore instanceof FKArrayStore) {
        if (backingStore instanceof FKSetStore) {
            iterStmt = ((FKSetStore) backingStore).getIteratorStatement(ec, ec.getFetchPlan(), false);
        } else if (backingStore instanceof FKListStore) {
            iterStmt = ((FKListStore) backingStore).getIteratorStatement(ec, ec.getFetchPlan(), false, -1, -1);
        } else if (backingStore instanceof FKArrayStore) {
            iterStmt = ((FKArrayStore) backingStore).getIteratorStatement(ec, ec.getFetchPlan(), false);
        } else {
            throw new NucleusUserException("We do not support BulkFetch using EXISTS for backingStore = " + backingStore);
        }
        // Set/List/array using foreign-key : Generate an iterator query of the form
        // SELECT ELEM_TBL.COL1, ELEM_TBL.COL2, ... FROM ELEM_TBL
        // WHERE EXISTS (SELECT OWNER_TBL.ID FROM OWNER_TBL WHERE (queryWhereClause) AND ELEM_TBL.OWNER_ID = OWNER_TBL.ID)
        SelectStatement sqlStmt = iterStmt.getSelectStatement();
        // Generate the EXISTS subquery (based on the JDOQL/JPQL query)
        SelectStatement existsStmt = RDBMSQueryUtils.getStatementForCandidates(storeMgr, sqlStmt, candidateCmd, datastoreCompilation.getResultDefinitionForClass(), ec, query.getCandidateClass(), query.isSubclasses(), query.getResult(), null, null, null);
        Set<String> options = new HashSet<>();
        if (mapperOptions != null) {
            options.addAll(mapperOptions);
        }
        options.add(QueryToSQLMapper.OPTION_SELECT_CANDIDATE_ID_ONLY);
        QueryToSQLMapper sqlMapper = new QueryToSQLMapper(existsStmt, query.getCompilation(), parameters, null, null, candidateCmd, query.isSubclasses(), query.getFetchPlan(), ec, query.getParsedImports(), options, query.getExtensions());
        sqlMapper.compile();
        // Add EXISTS clause on iterator statement so we can restrict to just the owners in this query
        // ORDER BY in EXISTS is forbidden by some RDBMS
        existsStmt.setOrdering(null, null);
        BooleanExpression existsExpr = new BooleanSubqueryExpression(sqlStmt, "EXISTS", existsStmt);
        sqlStmt.whereAnd(existsExpr, true);
        // Join to outer statement so we restrict to collection elements for the query candidates
        SQLExpression elemTblOwnerExpr = sqlStmt.getRDBMSManager().getSQLExpressionFactory().newExpression(sqlStmt, sqlStmt.getPrimaryTable(), ((BaseContainerStore) backingStore).getOwnerMapping());
        SQLExpression existsOwnerExpr = sqlStmt.getRDBMSManager().getSQLExpressionFactory().newExpression(existsStmt, existsStmt.getPrimaryTable(), existsStmt.getPrimaryTable().getTable().getIdMapping());
        existsStmt.whereAnd(elemTblOwnerExpr.eq(existsOwnerExpr), true);
        // Select the owner candidate so we can separate the collection elements out to their owner
        int[] ownerColIndexes = sqlStmt.select(elemTblOwnerExpr, null);
        StatementMappingIndex ownerMapIdx = new StatementMappingIndex(existsStmt.getPrimaryTable().getTable().getIdMapping());
        ownerMapIdx.setColumnPositions(ownerColIndexes);
        iterStmt.setOwnerMapIndex(ownerMapIdx);
    }
    return iterStmt;
}
Also used : JoinArrayStore(org.datanucleus.store.rdbms.scostore.JoinArrayStore) HashSet(java.util.HashSet) Set(java.util.Set) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) IteratorStatement(org.datanucleus.store.rdbms.scostore.IteratorStatement) BaseContainerStore(org.datanucleus.store.rdbms.scostore.BaseContainerStore) JoinArrayStore(org.datanucleus.store.rdbms.scostore.JoinArrayStore) FKArrayStore(org.datanucleus.store.rdbms.scostore.FKArrayStore) JoinSetStore(org.datanucleus.store.rdbms.scostore.JoinSetStore) JoinListStore(org.datanucleus.store.rdbms.scostore.JoinListStore) FKListStore(org.datanucleus.store.rdbms.scostore.FKListStore) FKSetStore(org.datanucleus.store.rdbms.scostore.FKSetStore) Store(org.datanucleus.store.types.scostore.Store) SelectStatement(org.datanucleus.store.rdbms.sql.SelectStatement) JoinSetStore(org.datanucleus.store.rdbms.scostore.JoinSetStore) BooleanExpression(org.datanucleus.store.rdbms.sql.expression.BooleanExpression) FKArrayStore(org.datanucleus.store.rdbms.scostore.FKArrayStore) BaseContainerStore(org.datanucleus.store.rdbms.scostore.BaseContainerStore) HashSet(java.util.HashSet) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) JoinListStore(org.datanucleus.store.rdbms.scostore.JoinListStore) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) ExecutionContext(org.datanucleus.ExecutionContext) BooleanSubqueryExpression(org.datanucleus.store.rdbms.sql.expression.BooleanSubqueryExpression) FKSetStore(org.datanucleus.store.rdbms.scostore.FKSetStore) FKListStore(org.datanucleus.store.rdbms.scostore.FKListStore) JoinTable(org.datanucleus.store.rdbms.table.JoinTable)

Example 23 with ClassLoaderResolver

use of org.datanucleus.ClassLoaderResolver in project datanucleus-rdbms by datanucleus.

the class BulkFetchJoinHandler method getStatementToBulkFetchField.

/**
 * Convenience method to generate a bulk-fetch statement for the specified multi-valued field of the owning query.
 * @param candidateCmd Metadata for the candidate
 * @param mmd Metadata for the member we are bulk-fetching the value(s) for
 * @param query The query
 * @param parameters Parameters for the query
 * @param datastoreCompilation The datastore compilation of the query
 * @param mapperOptions Any mapper options for query generation
 * @return The statement to use for bulk fetching, together with mappings for extracting the results of the elements
 */
public IteratorStatement getStatementToBulkFetchField(AbstractClassMetaData candidateCmd, AbstractMemberMetaData mmd, Query query, Map parameters, RDBMSQueryCompilation datastoreCompilation, Set<String> mapperOptions) {
    ExecutionContext ec = query.getExecutionContext();
    ClassLoaderResolver clr = ec.getClassLoaderResolver();
    RDBMSStoreManager storeMgr = (RDBMSStoreManager) query.getStoreManager();
    Store backingStore = storeMgr.getBackingStoreForField(clr, mmd, null);
    if (backingStore instanceof JoinSetStore || backingStore instanceof JoinListStore || backingStore instanceof JoinArrayStore) {
    // Set/List/array using join-table : Generate an iterator query of the form
    // SELECT ELEM_TBL.COL1, ELEM_TBL.COL2, ... FROM CANDIDATE_TBL T1 INNER JOIN JOIN_TBL T2 ON T2.OWNER_ID = T1.ID INNER_JOIN ELEM_TBL T3 ON T3.ID = T2.ELEM_ID
    // WHERE (queryWhereClause)
    // TODO Start from the original query, and remove any grouping, having, ordering etc, and join to join table + element table.
    } else if (backingStore instanceof FKSetStore || backingStore instanceof FKListStore || backingStore instanceof FKArrayStore) {
    // Set/List/array using foreign-key : Generate an iterator query of the form
    // SELECT ELEM_TBL.COL1, ELEM_TBL.COL2, ... FROM ELEM_TBL
    // WHERE EXISTS (SELECT OWNER_TBL.ID FROM OWNER_TBL WHERE (queryWhereClause) AND ELEM_TBL.OWNER_ID = OWNER_TBL.ID)
    // TODO Start from the original query, and remove any grouping, having, ordering etc, and join to element table.
    }
    throw new NucleusException("BulkFetch via JOIN is not yet implemented");
// return iterStmt;
}
Also used : JoinSetStore(org.datanucleus.store.rdbms.scostore.JoinSetStore) ExecutionContext(org.datanucleus.ExecutionContext) JoinArrayStore(org.datanucleus.store.rdbms.scostore.JoinArrayStore) FKSetStore(org.datanucleus.store.rdbms.scostore.FKSetStore) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) JoinListStore(org.datanucleus.store.rdbms.scostore.JoinListStore) FKListStore(org.datanucleus.store.rdbms.scostore.FKListStore) JoinArrayStore(org.datanucleus.store.rdbms.scostore.JoinArrayStore) FKSetStore(org.datanucleus.store.rdbms.scostore.FKSetStore) Store(org.datanucleus.store.types.scostore.Store) FKArrayStore(org.datanucleus.store.rdbms.scostore.FKArrayStore) JoinSetStore(org.datanucleus.store.rdbms.scostore.JoinSetStore) FKArrayStore(org.datanucleus.store.rdbms.scostore.FKArrayStore) JoinListStore(org.datanucleus.store.rdbms.scostore.JoinListStore) NucleusException(org.datanucleus.exceptions.NucleusException) FKListStore(org.datanucleus.store.rdbms.scostore.FKListStore) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager)

Example 24 with ClassLoaderResolver

use of org.datanucleus.ClassLoaderResolver in project datanucleus-rdbms by datanucleus.

the class ReferenceIdMapping method setObject.

/**
 * Method to set the object based on an input identity.
 * @param ec execution context
 * @param ps PreparedStatement
 * @param param Parameter positions to populate when setting the value
 * @param value The identity
 */
public void setObject(ExecutionContext ec, PreparedStatement ps, int[] param, Object value) {
    if (value == null) {
        super.setObject(ec, ps, param, null);
        return;
    }
    if (mappingStrategy == ID_MAPPING || mappingStrategy == XCALIA_MAPPING) {
        String refString = getReferenceStringForObject(ec, value);
        getJavaTypeMapping()[0].setString(ec, ps, param, refString);
        return;
    }
    ClassLoaderResolver clr = ec.getClassLoaderResolver();
    int colPos = 0;
    for (int i = 0; i < javaTypeMappings.length; i++) {
        int[] cols = new int[javaTypeMappings[i].getNumberOfColumnMappings()];
        for (int j = 0; j < cols.length; j++) {
            cols[j] = param[colPos++];
        }
        Class cls = clr.classForName(javaTypeMappings[i].getType());
        AbstractClassMetaData implCmd = ec.getMetaDataManager().getMetaDataForClass(cls, clr);
        if (implCmd.getObjectidClass().equals(value.getClass().getName())) {
            if (IdentityUtils.isDatastoreIdentity(value)) {
                Object key = IdentityUtils.getTargetKeyForDatastoreIdentity(value);
                if (key instanceof String) {
                    javaTypeMappings[i].setString(ec, ps, cols, (String) key);
                } else {
                    javaTypeMappings[i].setObject(ec, ps, cols, key);
                }
            } else if (IdentityUtils.isSingleFieldIdentity(value)) {
                Object key = IdentityUtils.getTargetKeyForSingleFieldIdentity(value);
                if (key instanceof String) {
                    javaTypeMappings[i].setString(ec, ps, cols, (String) key);
                } else {
                    javaTypeMappings[i].setObject(ec, ps, cols, key);
                }
            } else {
                // TODO Cater for compound identity
                String[] pkMemberNames = implCmd.getPrimaryKeyMemberNames();
                for (int j = 0; j < pkMemberNames.length; j++) {
                    Object pkMemberValue = ClassUtils.getValueForIdentityField(value, pkMemberNames[j]);
                    if (pkMemberValue instanceof Byte) {
                        getColumnMapping(j).setByte(ps, param[j], (Byte) pkMemberValue);
                    } else if (pkMemberValue instanceof Character) {
                        getColumnMapping(j).setChar(ps, param[j], (Character) pkMemberValue);
                    } else if (pkMemberValue instanceof Integer) {
                        getColumnMapping(j).setInt(ps, param[j], (Integer) pkMemberValue);
                    } else if (pkMemberValue instanceof Long) {
                        getColumnMapping(j).setLong(ps, param[j], (Long) pkMemberValue);
                    } else if (pkMemberValue instanceof Short) {
                        getColumnMapping(j).setShort(ps, param[j], (Short) pkMemberValue);
                    } else if (pkMemberValue instanceof String) {
                        getColumnMapping(j).setString(ps, param[j], (String) pkMemberValue);
                    } else {
                        getColumnMapping(j).setObject(ps, param[j], pkMemberValue);
                    }
                }
            }
        } else {
            // Set columns to null for this implementation
            javaTypeMappings[i].setObject(ec, ps, cols, null);
        }
    }
}
Also used : ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData)

Example 25 with ClassLoaderResolver

use of org.datanucleus.ClassLoaderResolver in project datanucleus-rdbms by datanucleus.

the class SimpleNumericAggregateMethod method getExpression.

/* (non-Javadoc)
     * @see org.datanucleus.store.rdbms.sql.method.SQLMethod#getExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression, java.util.List)
     */
public SQLExpression getExpression(SQLStatement stmt, SQLExpression expr, List<SQLExpression> args) {
    if (expr != null) {
        throw new NucleusException(Localiser.msg("060002", getFunctionName(), expr));
    }
    if (args == null || args.size() != 1) {
        throw new NucleusException(getFunctionName() + " is only supported with a single argument");
    }
    if (stmt.getQueryGenerator().getCompilationComponent() == CompilationComponent.RESULT || stmt.getQueryGenerator().getCompilationComponent() == CompilationComponent.HAVING) {
        // FUNC(argExpr)
        // Use same java type as the argument
        SQLExpression argExpr = args.get(0);
        JavaTypeMapping m = argExpr.getJavaTypeMapping();
        return new AggregateNumericExpression(stmt, m, getFunctionName(), args);
    }
    ClassLoaderResolver clr = stmt.getQueryGenerator().getClassLoaderResolver();
    // Handle as Subquery "SELECT AVG(expr) FROM tbl"
    SQLExpression argExpr = args.get(0);
    SelectStatement subStmt = new SelectStatement(stmt, stmt.getRDBMSManager(), argExpr.getSQLTable().getTable(), argExpr.getSQLTable().getAlias(), null);
    subStmt.setClassLoaderResolver(clr);
    SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
    JavaTypeMapping mapping = stmt.getRDBMSManager().getMappingManager().getMappingWithColumnMapping(String.class, false, false, clr);
    String aggregateString = getFunctionName() + "(" + argExpr.toSQLText() + ")";
    SQLExpression aggExpr = exprFactory.newLiteral(subStmt, mapping, aggregateString);
    ((StringLiteral) aggExpr).generateStatementWithoutQuotes();
    subStmt.select(aggExpr, null);
    JavaTypeMapping subqMapping = exprFactory.getMappingForType(Integer.class, false);
    SQLExpression subqExpr = new NumericSubqueryExpression(stmt, subStmt);
    subqExpr.setJavaTypeMapping(subqMapping);
    return subqExpr;
}
Also used : SelectStatement(org.datanucleus.store.rdbms.sql.SelectStatement) SQLExpressionFactory(org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) StringLiteral(org.datanucleus.store.rdbms.sql.expression.StringLiteral) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) AggregateNumericExpression(org.datanucleus.store.rdbms.sql.expression.AggregateNumericExpression) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) NucleusException(org.datanucleus.exceptions.NucleusException) NumericSubqueryExpression(org.datanucleus.store.rdbms.sql.expression.NumericSubqueryExpression)

Aggregations

ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)242 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)94 MetaDataManager (org.datanucleus.metadata.MetaDataManager)72 NucleusContext (org.datanucleus.NucleusContext)68 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)65 DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)65 PersistenceNucleusContextImpl (org.datanucleus.PersistenceNucleusContextImpl)56 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)56 ClassMetaData (org.datanucleus.metadata.ClassMetaData)54 JPAMetaDataManager (org.datanucleus.api.jpa.metadata.JPAMetaDataManager)51 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)44 NucleusException (org.datanucleus.exceptions.NucleusException)42 PersistenceUnitMetaData (org.datanucleus.metadata.PersistenceUnitMetaData)40 SQLExpressionFactory (org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory)40 SQLExpression (org.datanucleus.store.rdbms.sql.expression.SQLExpression)39 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)37 ArrayList (java.util.ArrayList)36 ExecutionContext (org.datanucleus.ExecutionContext)32 SelectStatement (org.datanucleus.store.rdbms.sql.SelectStatement)30 HashMap (java.util.HashMap)28