Search in sources :

Example 1 with ClassNotPersistableException

use of org.datanucleus.exceptions.ClassNotPersistableException in project datanucleus-rdbms by datanucleus.

the class SQLQuery method compileInternal.

/**
 * Verify the elements of the query and provide a hint to the query to prepare and optimize an execution plan.
 */
public void compileInternal(Map parameterValues) {
    if (isCompiled) {
        return;
    }
    // Default to using the users SQL direct with no substitution of params etc
    compiledSQL = inputSQL;
    if (candidateClass != null && getType() == QueryType.SELECT) {
        // Perform any sanity checking of input for SELECT queries
        RDBMSStoreManager storeMgr = (RDBMSStoreManager) getStoreManager();
        ClassLoaderResolver clr = ec.getClassLoaderResolver();
        AbstractClassMetaData cmd = ec.getMetaDataManager().getMetaDataForClass(candidateClass, clr);
        if (cmd == null) {
            throw new ClassNotPersistableException(candidateClass.getName());
        }
        if (cmd.getPersistableSuperclass() != null) {
        // throw new PersistentSuperclassNotAllowedException(candidateClass.getName());
        }
        if (getResultClass() == null) {
            if (getBooleanExtensionProperty(EXTENSION_SQL_SYNTAX_CHECKS, true)) {
                // Check syntax for the presence of the required columns (id, version, discriminator) in the candidate class
                // Skip "SELECT "
                String selections = stripComments(compiledSQL.trim()).substring(7);
                int fromStart = selections.indexOf("FROM");
                if (fromStart == -1) {
                    fromStart = selections.indexOf("from");
                }
                selections = selections.substring(0, fromStart).trim();
                String[] selectedColumns = StringUtils.split(selections, ",");
                if (selectedColumns == null || selectedColumns.length == 0) {
                    throw new NucleusUserException(Localiser.msg("059003", compiledSQL));
                }
                if (selectedColumns.length == 1 && selectedColumns[0].trim().equals("*")) {
                // SQL Query using * so just end the checking since all possible columns will be selected
                } else {
                    // Generate id column field information for later checking the id is present
                    DatastoreClass table = storeMgr.getDatastoreClass(candidateClass.getName(), clr);
                    PersistableMapping idMapping = (PersistableMapping) table.getIdMapping();
                    String[] idColNames = new String[idMapping.getNumberOfColumnMappings()];
                    boolean[] idColMissing = new boolean[idMapping.getNumberOfColumnMappings()];
                    for (int i = 0; i < idMapping.getNumberOfColumnMappings(); i++) {
                        idColNames[i] = idMapping.getColumnMapping(i).getColumn().getIdentifier().toString();
                        idColMissing[i] = true;
                    }
                    // Generate discriminator/version information for later checking they are present
                    JavaTypeMapping discrimMapping = table.getSurrogateMapping(SurrogateColumnType.DISCRIMINATOR, false);
                    String discriminatorColName = (discrimMapping != null) ? discrimMapping.getColumnMapping(0).getColumn().getIdentifier().toString() : null;
                    JavaTypeMapping versionMapping = table.getSurrogateMapping(SurrogateColumnType.VERSION, false);
                    String versionColName = (versionMapping != null) ? versionMapping.getColumnMapping(0).getColumn().getIdentifier().toString() : null;
                    boolean discrimMissing = (discriminatorColName != null);
                    boolean versionMissing = (versionColName != null);
                    // Go through the selected fields and check the existence of id, version, discriminator cols
                    DatastoreAdapter dba = storeMgr.getDatastoreAdapter();
                    final AbstractClassMetaData candidateCmd = ec.getMetaDataManager().getMetaDataForClass(candidateClass, clr);
                    for (int i = 0; i < selectedColumns.length; i++) {
                        String colName = selectedColumns[i].trim();
                        if (colName.indexOf(" AS ") > 0) {
                            // Allow for user specification of "XX.YY AS ZZ"
                            colName = colName.substring(colName.indexOf(" AS ") + 4).trim();
                        } else if (colName.indexOf(" as ") > 0) {
                            // Allow for user specification of "XX.YY as ZZ"
                            colName = colName.substring(colName.indexOf(" as ") + 4).trim();
                        } else if (colName.indexOf(".") > 0) {
                            // Note that this assumes the alias is the candidate table
                            colName = colName.substring(colName.indexOf(".") + 1);
                        }
                        if (candidateCmd.getIdentityType() == IdentityType.DATASTORE) {
                            // Check for existence of id column, allowing for any RDBMS using quoted identifiers
                            if (SQLQuery.columnNamesAreTheSame(dba, idColNames[0], colName)) {
                                idColMissing[0] = false;
                            }
                        } else if (candidateCmd.getIdentityType() == IdentityType.APPLICATION) {
                            for (int j = 0; j < idColNames.length; j++) {
                                // Check for existence of id column, allowing for any RDBMS using quoted identifiers
                                if (SQLQuery.columnNamesAreTheSame(dba, idColNames[j], colName)) {
                                    idColMissing[j] = false;
                                }
                            }
                        }
                        if (discrimMissing && SQLQuery.columnNamesAreTheSame(dba, discriminatorColName, colName)) {
                            discrimMissing = false;
                        } else if (versionMissing && SQLQuery.columnNamesAreTheSame(dba, versionColName, colName)) {
                            versionMissing = false;
                        }
                    }
                    if (discrimMissing) {
                        throw new NucleusUserException(Localiser.msg("059014", compiledSQL, candidateClass.getName(), discriminatorColName));
                    }
                    if (versionMissing) {
                        throw new NucleusUserException(Localiser.msg("059015", compiledSQL, candidateClass.getName(), versionColName));
                    }
                    for (int i = 0; i < idColMissing.length; i++) {
                        if (idColMissing[i]) {
                            throw new NucleusUserException(Localiser.msg("059013", compiledSQL, candidateClass.getName(), idColNames[i]));
                        }
                    }
                }
            }
        }
    }
    if (NucleusLogger.QUERY.isDebugEnabled()) {
        NucleusLogger.QUERY.debug(Localiser.msg("059012", compiledSQL));
    }
    isCompiled = true;
}
Also used : JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) PersistableMapping(org.datanucleus.store.rdbms.mapping.java.PersistableMapping) DatastoreAdapter(org.datanucleus.store.rdbms.adapter.DatastoreAdapter) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) ClassNotPersistableException(org.datanucleus.exceptions.ClassNotPersistableException)

Aggregations

ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)1 ClassNotPersistableException (org.datanucleus.exceptions.ClassNotPersistableException)1 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)1 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)1 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)1 DatastoreAdapter (org.datanucleus.store.rdbms.adapter.DatastoreAdapter)1 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)1 PersistableMapping (org.datanucleus.store.rdbms.mapping.java.PersistableMapping)1 DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)1