When i am writing the .save() in grails it is inserting a new row in the db table. However, not persisting data in the object.
I have tried with .save(flush: true) but had no luck.
Please help.
Thanks
Try save(failOnError:true) or check the return value of save() -- which is success/failure in Groovy-truth.
You can also add logSql: true to your application.yml datasource and
logger 'org.hibernate.type.descriptor.sql.BasicBinder', TRACE, ['STDOUT']
logger 'org.hibernate.SQL', TRACE, ['STDOUT']
to your logback.groovy
Probably the object you want to save is not validated. Means that not match with the minimum constraints described on the domain class.
Debug your code and run the validated method, after that take a look on the errors property.
object.validate()
object.errors
Take a look
https://docs.grails.org/latest/ref/Constraints/Usage.html
Remember that all not declared attributes on the constraints closure, are compulsory by default for saving the object
Related
I want to understand that ordering of Flush and Validate in Grails save method matters?
I have code snippet as : entity.save(flush: true, validate: false) and entity.save(validate: false, flush: true) in which first one is not saving any data but the later one is updating the database table.
Can someone help me to understand this?
Not it does not. This syntax is shorthand for ...save({validate:false, ...}). So this passes a map to that function. Maps are not ordered/sorted (well the map literal in groovy actually creates an ordered one for you, but that does not matter).
The order of validate and flush is defined in the code handling the save function. See GormInstanceApi.doSave.
RaceRegistration domain has embedded raceParticipant and raceParticipant has a field bibNumber which is Integer.
I have a method for nulling out all bibNumbers of registrations but without flush:true in save, the nulling out of bibs dont work. The bibs are not set to null.
def nullifyBibNumbers(Long id){
...
def regss = RaceRegistration.createCriteria().list(){
eq('compositeEvent', event)
}
regss.each{ r ->
r.raceParticipant.bibNumber = null
r.save()
}
render "Bibs resetted!"
}
If i add flush:true then the bibs are set to null.
regss.each{ r ->
r.raceParticipant.bibNumber = null
r.save(flush: true)
}
I am wondering why you need flush in order for the value to be set to null? I am guessing the problem is with regard to how i am obtain the registration list using createCriteria(). I appreciate any help in this dilemma i am facing. Thanks!
As you probably figured out, save(flush: true) forces Hibernate to write any pending changes to the database. Without the explicit flush, you're relying on a Hibernate transaction to automatically flush when the transaction commits.
The reason only an explicit flush is working for you is because you're not calling save() within a transaction.
The cleanest fix is to create a Grails service, put nullifyBibNumbers() in it, and make the service transactional. That will cause nullifyBibNumbers() to get wrapped in a transaction so that you can use save() without an explicit flush.
If nullifyBibNumbers() is already in a service, you can add #Transactional to the service class, just keep in mind that it will make all methods (perhaps only the public ones?) transactional. Having said that, you can use #NotTransactional on a method to disable transactions.
The value is null in your domain object. But you are talking about null in the database, I guess?
It shouldn't matter. This is basic ORM. As a developer you don't care about when the flush is done. Typically this would be at the end of a transaction. The ORM will then flush all of the changes for that transaction at once.
It works on what is called the first-level cache during the transaction, and tries to avoid going to the db until it is explicitly requested (flush:true) or required (end of transaction).
Without the using of
save(flush: true)
The object will not be persisted immediately.
You can follow the documentation link and see the following information:
The save method informs the persistence context that an instance
should be saved or updated. The object will not be persisted
immediately unless the flush argument is used.
Related to the null issue you are facing make sure that the following condition are met.
The save method returns null if validation failed and the instance was
not persisted, or the instance itself if successful.
You do not need the flush in order for the value to be set to null.
The flush only care of a quick update of the database.
ok i fixed this problem using HQL instead of domain saves. Still i would appreciate why save() didnt work and save(flush:true) saved the data. Thanks!
RaceRegistration.executeUpdate("update RaceRegistration set raceParticipant.bibNumber = null where compositeEvent.id = :ev", [ev: id])
In my Grails App, I have bootstrapped an object of a domain class as:
def user1 = new Users(userID: 1, name: "John Doe")
user1.save()
In my dashboard controller i have retrieved the object and modified its property name as:
Users userObj = Users.get((Long) 1)
println(userObj as JSON); // This gives me: {"class":"com.prabin.domains.Users","id":1,"name":"John Doe"}
userObj.name = "anonymous"
Now i create a new Users object to retrieve the changed object with same ID 1 as
Users otherUserObj = Users.get((Long) 1) // **Line 2** Is this retrieving from database or from GORM session?
print(otherUserObj as JSON)// This gives me: {"class":"com.prabin.domains.Users","id":1,"name":"anonymous"}
But the value of object in database is not changed. And even when i retrieve the Users object of same id 1 in another controller it gives me the initial object rather than the modified as:
Users userObjAtDifferentController = Users.get(1);
print(userObjAtDifferentController) //This gives me: {"class":"com.prabin.domains.Users","id":1,"name":"John Doe"}
My question is, if the value is not changed in the database, why it gives me the modified object at Line 2 though i have retrieved the object using GORM query (which i guess should retrieve from the database)?
I have also tried using save() after the modification but the result is same.
userObj.save() //doesn't show the changes in database.
My guess is that the object is not being saved to the database because some constraint(s) are invalid. You can determine whether this is the case by replacing your calls to save() with save(failOnError: true). If my guess is correct, an exception will be thrown if saving to the database fails.
When you call the save() method on a domain object, it may not persist in the database immediately. In order to persist the changed value to the database, you would need to do the following.
userObj.save(flush: true)
By using flush, you are telling GORM to persist immediately in the database.
In some cases when validation fails, the data will still not persist in the database. The save() method will fail silently. To catch validation errors as well as save to the database immediately, you would want to do the following
userObj.save(flush:true, failOnError:true)
If validation errors exist, then the GROM will throw ValidationException (http://docs.grails.org/latest/api/grails/validation/ValidationException.html)
You need to consider two things:
If you do save(), it only retains in hibernate session, until you flush it the changes does not persist in database. So, better do save(flush:true, failOnError: true) and put in try/catch block and print exception.
And another important things is, your method in controller needs to be with #Transactional annotation, without it your changes does not persist in database, you will encounter Connection is read-only. Queries leading to data modification are not allowed. exception.
Hope this helps, let me know if your issue is fixed. Happy coding . :)
How do I delete all session variables at once if they are not in Array?
PS I set them this way:
$this->getUser()->setAttribute('PayPalTransaction.hash', $request->getParameter('hash'));
Regards,
Roman
The sfUser class (which you get with $this->getUser()), keeps all it's attributes in a sfNamespacedParameterHolder. So the setAttribute() function on sfUser if merely a proxy to the sfNamespacedParameterHolder::setAttribute(). You can get the reference to this holder with sfUser::getAttributeHolder().
The sfNamespacedParameterHolder also has a function clear(), which clears all attributes.
So to clear all attributes, use:
$this->getUser()->getAttributeHolder()->clear().
(Please note that you will still be authenticated (e.g. logged in) when you clear the attribute holder).
Another way if you want to remove just one session variable not all of them is to use the following code
$this->getUser()->getAttributeHolder()->remove('att_name');
Again this will only remove one not all ... to clear all use the previous code by Grad
To remove all attributes of a namespace :
$this->getUser()->getAttributeHolder()->removeNamespace('yournamespace');
Is it possible to use the Searchable Plugin to create an index of objects and never actually save the objects to the database?
I think so. If you never save the objects, then I think you can just call:
domainInstance.index()
But I've never tried it, so I'm not sure if it just indexes the one instance, or any instance of that class.
See here:
https://svn.codehaus.org/grails-plugins/grails-searchable/trunk/src/groovy/org/codehaus/groovy/grails/plugins/searchable/compass/domain/DynamicDomainMethodUtils.groovy
If you just want to save the object but just want to index manually, then set the following in your conf/Searchable.groovy config file:
mirrorChanges = false
bulkIndexOnStartup = false
See here: https://svn.codehaus.org/grails-plugins/grails-searchable/trunk/src/conf/Searchable.groovy