D save()

in grails-datastore-gorm-hibernate/src/main/groovy/org/grails/orm/hibernate/AbstractHibernateGormInstanceApi.groovy [99:170]


    D save(D target, Map arguments) {

        PersistentEntity domainClass = persistentEntity
        runDeferredBinding()
        boolean shouldFlush = shouldFlush(arguments)
        boolean shouldValidate = shouldValidate(arguments, persistentEntity)

        HibernateRuntimeUtils.autoAssociateBidirectionalOneToOnes(domainClass, target)

        boolean deepValidate = true
        if (arguments?.containsKey(ARGUMENT_DEEP_VALIDATE)) {
            deepValidate = ClassUtils.getBooleanFromMap(ARGUMENT_DEEP_VALIDATE, arguments)
        }

        if (shouldValidate) {
            Validator validator = datastore.mappingContext.getEntityValidator(domainClass)

            Errors errors = HibernateRuntimeUtils.setupErrorsProperty(target)

            if (validator) {
                datastore.applicationEventPublisher?.publishEvent new ValidationEvent(datastore, target)

                if (validator instanceof CascadingValidator) {
                    ((CascadingValidator)validator).validate target, errors, deepValidate
                } else if (validator instanceof org.grails.datastore.gorm.validation.CascadingValidator) {
                    ((org.grails.datastore.gorm.validation.CascadingValidator) validator).validate target, errors, deepValidate
                } else {
                    validator.validate target, errors
                }

                if (errors.hasErrors()) {
                    handleValidationError(domainClass,target,errors)
                    if (shouldFail(arguments)) {
                        throw validationException.newInstance("Validation Error(s) occurred during save()", errors)
                    }
                    return null
                }

                setObjectToReadWrite(target)
            }
        }

        // this piece of code will retrieve a persistent instant
        // of a domain class property is only the id is set thus
        // relieving this burden off the developer
        autoRetrieveAssociations datastore, domainClass, target

        // Once we get here we've either validated this object or skipped validation, either way
        // we don't need to validate again for the rest of this save.
        GormValidateable validateable = (GormValidateable) target
        validateable.skipValidation(true)

        try {
            if (shouldInsert(arguments)) {
                return performInsert(target, shouldFlush)
            }
            else if(shouldMerge(arguments)) {
                return performMerge(target, shouldFlush)
            }
            else {
                if (target instanceof DirtyCheckable && markDirty) {
                    target.markDirty()
                }
                return performSave(target, shouldFlush)
            }
        } finally {
            // After save, we have to make sure this entity is setup to validate again. It's possible it will
            // be validated again if this save didn't flush, but without checking it's dirty state we can't really
            // know for sure that it hasn't changed and need to err on the side of caution.
            validateable.skipValidation(false)
        }
    }