Search in sources :

Example 86 with NucleusUserException

use of org.datanucleus.exceptions.NucleusUserException in project datanucleus-core by datanucleus.

the class StateManagerImpl method detachCopy.

/**
 * Method to make detached copy of this instance
 * If the object is detachable then the copy will be migrated to DETACHED state, otherwise will migrate
 * the copy to TRANSIENT. Used by "ExecutionContext.detachObjectCopy()".
 * @param state State for the detachment process
 * @return the detached Persistable instance
 */
public Persistable detachCopy(FetchPlanState state) {
    if (myLC.isDeleted()) {
        throw new NucleusUserException(Localiser.msg("026023", myPC.getClass().getName(), myID));
    }
    if (myEC.getApiAdapter().isDetached(myPC)) {
        throw new NucleusUserException(Localiser.msg("026024", myPC.getClass().getName(), myID));
    }
    if (dirty) {
        myEC.flushInternal(false);
    }
    if (isDetaching()) {
        // Object in the process of detaching (recursive) so return the object which will be the detached object
        return getReferencedPC();
    }
    // Look for an existing detached copy
    DetachState detachState = (DetachState) state;
    DetachState.Entry existingDetached = detachState.getDetachedCopyEntry(myPC);
    Persistable detachedPC;
    if (existingDetached == null) {
        // No existing detached copy - create new one
        detachedPC = myPC.dnNewInstance(this);
        detachState.setDetachedCopyEntry(myPC, detachedPC);
    } else {
        // Found one - if it's sufficient for current FetchPlanState, return it immediately
        detachedPC = (Persistable) existingDetached.getDetachedCopyObject();
        if (existingDetached.checkCurrentState()) {
            return detachedPC;
        }
    // Need to process the detached copy using current FetchPlanState
    }
    myEC.setAttachDetachReferencedObject(this, detachedPC);
    // Check if detachable ... if so then we detach a copy, otherwise we return a transient copy
    boolean detachable = myEC.getApiAdapter().isDetachable(myPC);
    // make sure a detaching PC is not read by another thread while we are detaching
    Object referencedPC = getReferencedPC();
    synchronized (referencedPC) {
        int[] detachFieldNums = getFieldsNumbersToDetach();
        if (detachable) {
            if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
                int[] fieldsToLoad = null;
                if ((myEC.getFetchPlan().getDetachmentOptions() & FetchPlan.DETACH_LOAD_FIELDS) != 0) {
                    fieldsToLoad = ClassUtils.getFlagsSetTo(loadedFields, myFP.getMemberNumbers(), false);
                }
                NucleusLogger.PERSISTENCE.debug(Localiser.msg("010010", StringUtils.toJVMIDString(myPC), "" + state.getCurrentFetchDepth(), StringUtils.toJVMIDString(detachedPC), StringUtils.intArrayToString(detachFieldNums), StringUtils.intArrayToString(fieldsToLoad)));
            }
            // Call any "pre-detach" listeners
            getCallbackHandler().preDetach(myPC);
        }
        try {
            setDetaching(true);
            // Handle any field loading/unloading before the detach
            if ((myEC.getFetchPlan().getDetachmentOptions() & FetchPlan.DETACH_LOAD_FIELDS) != 0) {
                // Load any unloaded fetch-plan fields
                loadUnloadedFieldsInFetchPlan();
            }
            if (myLC == myEC.getNucleusContext().getApiAdapter().getLifeCycleState(LifeCycleState.HOLLOW) || myLC == myEC.getNucleusContext().getApiAdapter().getLifeCycleState(LifeCycleState.P_NONTRANS)) {
                // Migrate any HOLLOW/P_NONTRANS to P_CLEAN etc
                myLC = myLC.transitionReadField(this, true);
            }
            // Create a SM for our copy object
            ObjectProvider smDetachedPC = new StateManagerImpl(myEC, cmd);
            smDetachedPC.initialiseForDetached(detachedPC, getExternalObjectId(myPC), getVersion(myPC));
            myEC.setAttachDetachReferencedObject(smDetachedPC, myPC);
            // If detached copy already existed, take note of fields previously loaded
            if (existingDetached != null) {
                smDetachedPC.retrieveDetachState(smDetachedPC);
            }
            smDetachedPC.replaceFields(detachFieldNums, new DetachFieldManager(this, cmd.getSCOMutableMemberFlags(), myFP, state, true));
            myEC.setAttachDetachReferencedObject(smDetachedPC, null);
            if (detachable) {
                // Update the object with its detached state - not to be confused with the "state" object above
                detachedPC.dnReplaceFlags();
                ((Detachable) detachedPC).dnReplaceDetachedState();
            } else {
                smDetachedPC.makeTransient(null);
            }
            // Remove its StateManager since now detached or transient
            replaceStateManager(detachedPC, null);
        } catch (Exception e) {
            // What could possibly be wrong here ? Log it and let the user provide a testcase, yeah right
            NucleusLogger.PERSISTENCE.warn("DETACH ERROR : Error thrown while detaching " + StringUtils.toJVMIDString(myPC) + " (id=" + myID + "). Provide a testcase that demonstrates this", e);
        } finally {
            setDetaching(false);
            referencedPC = null;
        }
        if (detachable && !myEC.getApiAdapter().isDetached(detachedPC)) {
            // Sanity check on the objects detached state
            throw new NucleusUserException(Localiser.msg("026025", detachedPC.getClass().getName(), myID));
        }
        if (detachable) {
            // Call any "post-detach" listeners
            getCallbackHandler().postDetach(myPC, detachedPC);
        }
    }
    return detachedPC;
}
Also used : Detachable(org.datanucleus.enhancement.Detachable) Persistable(org.datanucleus.enhancement.Persistable) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) DetachFieldManager(org.datanucleus.store.fieldmanager.DetachFieldManager) DetachState(org.datanucleus.DetachState) NucleusObjectNotFoundException(org.datanucleus.exceptions.NucleusObjectNotFoundException) NucleusException(org.datanucleus.exceptions.NucleusException) EndOfFetchPlanGraphException(org.datanucleus.store.fieldmanager.AbstractFetchDepthFieldManager.EndOfFetchPlanGraphException) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) ClassNotResolvedException(org.datanucleus.exceptions.ClassNotResolvedException) NotYetFlushedException(org.datanucleus.exceptions.NotYetFlushedException)

Example 87 with NucleusUserException

use of org.datanucleus.exceptions.NucleusUserException in project datanucleus-core by datanucleus.

the class StateManagerImpl method checkInheritance.

/**
 * Look to the database to determine which class this object is. This parameter is a hint. Set false, if it's
 * already determined the correct pcClass for this pc "object" in a certain
 * level in the hierarchy. Set to true and it will look to the database.
 * TODO This is only called by some outdated code in LDAPUtils; remove it when that is fixed
 * @param fv the initial field values of the object.
 * @deprecated Dont use this, to be removed
 */
public void checkInheritance(FieldValues fv) {
    // Inheritance case, check the level of the instance
    ClassLoaderResolver clr = myEC.getClassLoaderResolver();
    String className = getStoreManager().getClassNameForObjectID(myID, clr, myEC);
    if (className == null) {
        // className is null when id class exists, and object has been validated and doesn't exist.
        throw new NucleusObjectNotFoundException(Localiser.msg("026013", IdentityUtils.getPersistableIdentityForId(myID)), myID);
    } else if (!cmd.getFullClassName().equals(className)) {
        Class pcClass;
        try {
            // load the class and make sure the class is initialized
            pcClass = clr.classForName(className, myID.getClass().getClassLoader(), true);
            cmd = myEC.getMetaDataManager().getMetaDataForClass(pcClass, clr);
        } catch (ClassNotResolvedException e) {
            NucleusLogger.PERSISTENCE.warn(Localiser.msg("026014", IdentityUtils.getPersistableIdentityForId(myID)));
            throw new NucleusUserException(Localiser.msg("026014", IdentityUtils.getPersistableIdentityForId(myID)), e);
        }
        if (cmd == null) {
            throw new NucleusUserException(Localiser.msg("026012", pcClass)).setFatal();
        }
        if (cmd.getIdentityType() != IdentityType.APPLICATION) {
            throw new NucleusUserException("This method should only be used for objects using application identity.").setFatal();
        }
        myFP = myEC.getFetchPlan().getFetchPlanForClass(cmd);
        int fieldCount = cmd.getMemberCount();
        dirtyFields = new boolean[fieldCount];
        loadedFields = new boolean[fieldCount];
        // Create new PC at right inheritance level
        myPC = HELPER.newInstance(pcClass, this);
        if (myPC == null) {
            throw new NucleusUserException(Localiser.msg("026018", cmd.getFullClassName())).setFatal();
        }
        // Note that this will mean the fields are loaded twice (loaded earlier in this method)
        // and also that postLoad will be called twice
        loadFieldValues(fv);
        // Create the id for the new PC
        myID = myEC.getNucleusContext().getIdentityManager().getApplicationId(myPC, cmd);
    }
}
Also used : NucleusUserException(org.datanucleus.exceptions.NucleusUserException) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) FetchPlanForClass(org.datanucleus.FetchPlanForClass) NucleusObjectNotFoundException(org.datanucleus.exceptions.NucleusObjectNotFoundException) ClassNotResolvedException(org.datanucleus.exceptions.ClassNotResolvedException)

Example 88 with NucleusUserException

use of org.datanucleus.exceptions.NucleusUserException in project datanucleus-core by datanucleus.

the class AbstractStoreManager method getValueGenerationStrategyForNative.

/**
 * Method defining which value-strategy to use when the user specifies "native". This will return as follows
 * <ul>
 * <li>If your field is Numeric-based (or datastore-id with numeric or no jdbc-type) then chooses the
 * first one that is supported of "identity", "sequence", "increment", otherwise exception.</li>
 * <li>Otherwise your field is String-based then chooses "uuid-hex".</li>
 * </ul>
 * If your store plugin requires something else then override this
 * @param cmd Class requiring the strategy
 * @param absFieldNumber Field of the class
 * @return The strategy used when "native" is specified
 */
public String getValueGenerationStrategyForNative(AbstractClassMetaData cmd, int absFieldNumber) {
    if (absFieldNumber >= 0) {
        AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(absFieldNumber);
        Class type = mmd.getType();
        if (String.class.isAssignableFrom(type)) {
            // TODO Do we really want this when we have "uuid"?
            return ValueGenerationStrategy.UUIDHEX.toString();
        } else if (type == Long.class || type == Integer.class || type == Short.class || type == long.class || type == int.class || type == short.class || type == BigInteger.class) {
            if (supportsValueGenerationStrategy(ValueGenerationStrategy.IDENTITY.toString())) {
                return ValueGenerationStrategy.IDENTITY.toString();
            } else if (supportsValueGenerationStrategy(ValueGenerationStrategy.SEQUENCE.toString()) && mmd.getSequence() != null) {
                return ValueGenerationStrategy.SEQUENCE.toString();
            } else if (supportsValueGenerationStrategy(ValueGenerationStrategy.INCREMENT.toString())) {
                return ValueGenerationStrategy.INCREMENT.toString();
            }
            throw new NucleusUserException("This datastore provider doesn't support numeric native strategy for member " + mmd.getFullFieldName());
        } else {
            throw new NucleusUserException("This datastore provider doesn't support native strategy for field of type " + type.getName());
        }
    }
    IdentityMetaData idmd = cmd.getBaseIdentityMetaData();
    if (idmd != null && idmd.getColumnMetaData() != null) {
        if (MetaDataUtils.isJdbcTypeString(idmd.getColumnMetaData().getJdbcType())) {
            return ValueGenerationStrategy.UUIDHEX.toString();
        }
    }
    // Numeric datastore-identity
    if (supportsValueGenerationStrategy(ValueGenerationStrategy.IDENTITY.toString())) {
        return ValueGenerationStrategy.IDENTITY.toString();
    } else if (supportsValueGenerationStrategy(ValueGenerationStrategy.SEQUENCE.toString()) && idmd != null && idmd.getSequence() != null) {
        return ValueGenerationStrategy.SEQUENCE.toString();
    } else if (supportsValueGenerationStrategy(ValueGenerationStrategy.INCREMENT.toString())) {
        return ValueGenerationStrategy.INCREMENT.toString();
    }
    throw new NucleusUserException("This datastore provider doesn't support numeric native strategy for class " + cmd.getFullClassName());
}
Also used : BigInteger(java.math.BigInteger) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) IdentityMetaData(org.datanucleus.metadata.IdentityMetaData)

Example 89 with NucleusUserException

use of org.datanucleus.exceptions.NucleusUserException in project datanucleus-core by datanucleus.

the class AbstractStoreManager method getValueGeneratorForMember.

protected synchronized ValueGenerator getValueGeneratorForMember(ClassLoaderResolver clr, AbstractClassMetaData cmd, int absoluteFieldNumber) {
    String memberKey = valueGenerationMgr.getMemberKey(cmd, absoluteFieldNumber);
    // Check if we have a ValueGenerator already created for this member
    ValueGenerator generator = valueGenerationMgr.getValueGeneratorForMemberKey(memberKey);
    if (generator != null) {
        // Return the ValueGenerator already registered against this member "key"
        return generator;
    }
    // No ValueGenerator registered for this memberKey, so need to determine which to use and create it as required.
    String fieldName = null;
    ValueGenerationStrategy strategy = null;
    String sequence = null;
    String valueGeneratorName = null;
    if (absoluteFieldNumber >= 0) {
        // real field
        AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(absoluteFieldNumber);
        fieldName = mmd.getFullFieldName();
        strategy = mmd.getValueStrategy();
        sequence = mmd.getSequence();
        valueGeneratorName = mmd.getValueGeneratorName();
    } else {
        // datastore-identity surrogate field
        fieldName = cmd.getFullClassName() + " (datastore id)";
        strategy = cmd.getIdentityMetaData().getValueStrategy();
        sequence = cmd.getIdentityMetaData().getSequence();
        valueGeneratorName = cmd.getIdentityMetaData().getValueGeneratorName();
    }
    String strategyName = strategy.toString();
    if (strategy.equals(ValueGenerationStrategy.CUSTOM)) {
        // Using a "custom" generator
        strategyName = strategy.getCustomName();
    } else if (strategy.equals(ValueGenerationStrategy.NATIVE)) {
        strategyName = getValueGenerationStrategyForNative(cmd, absoluteFieldNumber);
        strategy = ValueGenerationStrategy.getIdentityStrategy(strategyName);
    }
    // Check for this strategy being a "unique" ValueGenerator, and created if not yet present
    generator = valueGenerationMgr.getUniqueValueGeneratorByName(strategyName);
    if (generator != null) {
        // "unique" ValueGenerator already defined for this strategy, so register it against the member
        valueGenerationMgr.registerValueGeneratorForMemberKey(memberKey, generator);
        return generator;
    }
    // Must be "datastore" specific generator so use plugin mechanism to create one and register against this member "key"
    // Set up the default properties available for all value generators
    // Extract any metadata-based generation information keyed by the "valueGeneratorName"
    TableGeneratorMetaData tableGeneratorMetaData = null;
    SequenceMetaData sequenceMetaData = null;
    if (valueGeneratorName != null) {
        if (strategy == ValueGenerationStrategy.INCREMENT) {
            tableGeneratorMetaData = getMetaDataManager().getMetaDataForTableGenerator(clr, valueGeneratorName);
            if (tableGeneratorMetaData == null) {
                throw new NucleusUserException(Localiser.msg("038005", fieldName, valueGeneratorName));
            }
        } else if (strategy == ValueGenerationStrategy.SEQUENCE) {
            sequenceMetaData = getMetaDataManager().getMetaDataForSequence(clr, valueGeneratorName);
            if (sequenceMetaData == null) {
                throw new NucleusUserException(Localiser.msg("038006", fieldName, valueGeneratorName));
            }
        }
    } else if (strategy == ValueGenerationStrategy.SEQUENCE && sequence != null) {
        // TODO Allow for package name of this class prefix for the sequence name
        sequenceMetaData = getMetaDataManager().getMetaDataForSequence(clr, sequence);
        if (sequenceMetaData == null) {
            // No <sequence> defining the datastore sequence name, so fallback to this name directly in the datastore
            NucleusLogger.VALUEGENERATION.info("Member " + fieldName + " has been specified to use sequence '" + sequence + "' but there is no <sequence> specified in the MetaData. Falling back to use a sequence in the datastore with this name directly.");
        }
    }
    Properties props = getPropertiesForValueGenerator(cmd, absoluteFieldNumber, clr, sequenceMetaData, tableGeneratorMetaData);
    return valueGenerationMgr.createAndRegisterValueGenerator(memberKey, strategyName, props);
}
Also used : NucleusUserException(org.datanucleus.exceptions.NucleusUserException) ValueGenerator(org.datanucleus.store.valuegenerator.ValueGenerator) ValueGenerationStrategy(org.datanucleus.metadata.ValueGenerationStrategy) TableGeneratorMetaData(org.datanucleus.metadata.TableGeneratorMetaData) Properties(java.util.Properties) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) SequenceMetaData(org.datanucleus.metadata.SequenceMetaData)

Example 90 with NucleusUserException

use of org.datanucleus.exceptions.NucleusUserException in project datanucleus-core by datanucleus.

the class TemporalMonthJavaMethod method evaluate.

/* (non-Javadoc)
     * @see org.datanucleus.query.evaluator.memory.InvocationEvaluator#evaluate(org.datanucleus.query.expression.InvokeExpression, org.datanucleus.query.evaluator.memory.InMemoryExpressionEvaluator)
     */
public Object evaluate(InvokeExpression expr, Object invokedValue, InMemoryExpressionEvaluator eval) {
    if (invokedValue == null && expr.getArguments() != null) {
        // Specified as static function, so use argument of InvokeExpression
        List<Expression> argExprs = expr.getArguments();
        if (argExprs.size() > 1) {
            throw new NucleusUserException("Incorrect number of arguments to MONTH_JAVA");
        }
        Expression argExpr = argExprs.get(0);
        invokedValue = eval.getValueForExpression(argExpr);
    }
    if (invokedValue == null) {
        return Boolean.FALSE;
    }
    if (!(invokedValue instanceof Date)) {
        throw new NucleusException(Localiser.msg("021011", expr.getOperation(), invokedValue.getClass().getName()));
    }
    if (invokedValue instanceof Date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime((Date) invokedValue);
        return Integer.valueOf(cal.get(Calendar.MONTH));
    } else if (invokedValue instanceof Calendar) {
        return Integer.valueOf(((Calendar) invokedValue).get(Calendar.MONTH));
    } else if (invokedValue instanceof LocalDate) {
        return ((LocalDate) invokedValue).getMonthValue() - 1;
    } else if (invokedValue instanceof LocalDateTime) {
        return ((LocalDateTime) invokedValue).getMonthValue() - 1;
    } else {
        throw new NucleusUserException("We do not currently support MONTH_JAVA() with argument of type " + invokedValue.getClass().getName());
    }
}
Also used : LocalDateTime(java.time.LocalDateTime) Expression(org.datanucleus.query.expression.Expression) InvokeExpression(org.datanucleus.query.expression.InvokeExpression) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) Calendar(java.util.Calendar) NucleusException(org.datanucleus.exceptions.NucleusException) LocalDate(java.time.LocalDate) Date(java.util.Date) LocalDate(java.time.LocalDate)

Aggregations

NucleusUserException (org.datanucleus.exceptions.NucleusUserException)258 NucleusException (org.datanucleus.exceptions.NucleusException)65 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)51 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)46 SQLExpression (org.datanucleus.store.rdbms.sql.expression.SQLExpression)46 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)41 DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)36 ArrayList (java.util.ArrayList)34 ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)30 ObjectProvider (org.datanucleus.state.ObjectProvider)30 ClassNotResolvedException (org.datanucleus.exceptions.ClassNotResolvedException)26 Expression (org.datanucleus.query.expression.Expression)24 InvokeExpression (org.datanucleus.query.expression.InvokeExpression)23 SQLException (java.sql.SQLException)22 PersistableMapping (org.datanucleus.store.rdbms.mapping.java.PersistableMapping)21 NullLiteral (org.datanucleus.store.rdbms.sql.expression.NullLiteral)21 SQLLiteral (org.datanucleus.store.rdbms.sql.expression.SQLLiteral)21 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)20 SQLExpressionFactory (org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory)20 BigInteger (java.math.BigInteger)19