Save info in a userprofile field on failing validation

Any issue about Cyclos 4 scripting and Webservices

Moderators: hugo, alexandre, rmvanarkel

Post Reply
sandrab
Posts: 13
Joined: Tue Sep 11, 2018 8:26 am

Save info in a userprofile field on failing validation

Post by sandrab » Tue Sep 11, 2018 9:46 am

Hi,

We have an extension script setup when validating users. I am trying to let this script save some information in a user profile field when the validation is failing. The relevant code is like this:

Code: Select all

def usr = scriptHelper.wrap(user)

// .. other code here ..

// .. a check indicates something is wrong ..
if (somethingWrong) {
	// Store relevant information in the userprofile and stop.
	usr.someField = 'abc'
	throw new ValidationException("Some message")
}

// .. other code here ..
This does not work, the value 'abc' is not saved in the userprofile field. Is this maybe because the ValidationException results in a rollback? Can I call some commit or save method just before throwing the ValidationException somehow?

Thanks,
Sandra

Using Cyclos 4.9.1

luis
Posts: 179
Joined: Fri Feb 17, 2006 11:01 am

Re: Save info in a userprofile field on failing validation

Post by luis » Wed Sep 12, 2018 8:17 am

sandrab wrote:
Tue Sep 11, 2018 9:46 am
Hi,

We have an extension script setup when validating users. I am trying to let this script save some information in a user profile field when the validation is failing. The relevant code is like this:

Code: Select all

def usr = scriptHelper.wrap(user)

// .. other code here ..

// .. a check indicates something is wrong ..
if (somethingWrong) {
	// Store relevant information in the userprofile and stop.
	usr.someField = 'abc'
	throw new ValidationException("Some message")
}

// .. other code here ..
This does not work, the value 'abc' is not saved in the userprofile field. Is this maybe because the ValidationException results in a rollback? Can I call some commit or save method just before throwing the ValidationException somehow?

Thanks,
Sandra

Using Cyclos 4.9.1
Exactly, throwing any exception rolls back the transaction.
You can use a transaction rollback callback for this. The callback is executed after the main transaction rolls back, in a new transaction. Just remember to fetch the user again, as it is a new transaction, and the previous user reference is detached. Example:

Code: Select all

if (somethingWrong) {
    scriptHelper.addOnRollbackTransactional {
        // Fetch the user again
        user = entityManagerHandler.find(user.class, user.id)
        usr = scriptHelper.wrap(user)
        // This will be persisted, as this new transaction will commit
        usr.someField = 'abc'
    }
    throw new ValidationException("Some message")
}
Luis Fernando Planella Gonzalez
Cyclos development team

luis
Posts: 179
Joined: Fri Feb 17, 2006 11:01 am

Re: Save info in a userprofile field on failing validation

Post by luis » Wed Sep 12, 2018 9:08 am

There is another alternative.
In the first solution, the rollback callback runs after the main transaction finishes.
If, for some reason, the server crashes in-between, the database state may be inconsistent.
The other solution involves opening a parallel transaction, in which you can wait until it finishes to later on throw the exception.
Here's how you'd do it:

Code: Select all

import org.cyclos.model.utils.TransactionLevel

// Save the user in a parallel transaction
def future = invokerHandler.runAsInParallelTransaction(sessionData, TransactionLevel.READ_WRITE) {
    // Fetch the user again
    user = entityManagerHandler.find(user.class, user.id)
    usr = scriptHelper.wrap(user)
    // This will be persisted, as this new transaction will commit
    usr.someField = 'abc'
}

// Wait for the transaction to finish
future.get()

// Only then throw the exception to rollback the main transaction
throw new ValidationException();
Luis Fernando Planella Gonzalez
Cyclos development team

sandrab
Posts: 13
Joined: Tue Sep 11, 2018 8:26 am

Re: Save info in a userprofile field on failing validation

Post by sandrab » Thu Sep 13, 2018 9:17 am

Hi Luis,

I tried your second solution and it works like a charm. Many thanks!

Sandra

Post Reply