GORM doesn't perform validate when addTo

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

GORM doesn't perform validate when addTo

jl_monteagudo
Hi all,

I'm having a problem when saving a domain class, because Grails is not performing the validation when I call an addTo method.

Here is the prolem:

+++++++++++++++++++++++++

class Content {
       
        String title
       
        static hasMany = [comments:Comment]
       
        static constraints = {
                title(blank:false, maxSize:55)
        }
       
}


+++++++++++++++++++++++++

class Comment {
       
        static belongsTo = [content:Content]
       
        String title
       
        static constraints = {
                title(blank:false)
        }
       
}

+++++++++++++++++++++++++++

class CommentTests extends GroovyTestCase {

    void testSaveComment() {
   
    Content c = new Content(title:"title")
    c.save(flush:true)
   
    Comment m = new Comment(title:"")
    c.addToComments(m)
    //c.save(flush:true)
   
    def comments = Comment.list()
    println "comments number:" + comments.size()
   
    if (m.validate()) {
    println "valid comment"
    }
    else {
    println "INVALID comment"
    }

    }
}

++++++++++++++++++++++++++++

------------- Standard Output ---------------
--Output from testSaveComment--
comments number:1
INVALID comment
------------- ---------------- ---------------

As you can see, the domain "comment" is not correct, because I've defined that its title property can not be blank, but when I add this "comment" to the "content" it is being saved into the database. But if I check if the comment is valid invoking "m.validate()" you can see that GORM know that it is not correct.

I've attached the project, so if you want you can check it.

So, please, do you know if I can solve this problem in any way?

Another question is, if I invoke the method "c.addToComments(m)", then the "comment" has to be directly saved into the database ??? I thought that I was to call explicitly the method "c.save()" in order to the "comment" were saved into the database.

Could you help me with these issues, please ???

Thank you very much in advance.



t1.zip
Reply | Threaded
Open this post in threaded view
|

Re: GORM doesn't perform validate when addTo

jl_monteagudo
Hello all,

Does anybody have this problem?

I think that I'm doing a very common task when programming with Grails, so I suppose that a lot of people should experiment this problem. Nobody is having this problem ???

This is making me wonder if I'm doing something wrong.    Althought it is a very basic task, so I don't think that it's my fault.

Any suggestion, please ???





jl_monteagudo wrote
Hi all,

I'm having a problem when saving a domain class, because Grails is not performing the validation when I call an addTo method.

Here is the prolem:

+++++++++++++++++++++++++

class Content {
       
        String title
       
        static hasMany = [comments:Comment]
       
        static constraints = {
                title(blank:false, maxSize:55)
        }
       
}


+++++++++++++++++++++++++

class Comment {
       
        static belongsTo = [content:Content]
       
        String title
       
        static constraints = {
                title(blank:false)
        }
       
}

+++++++++++++++++++++++++++

class CommentTests extends GroovyTestCase {

    void testSaveComment() {
   
    Content c = new Content(title:"title")
    c.save(flush:true)
   
    Comment m = new Comment(title:"")
    c.addToComments(m)
    //c.save(flush:true)
   
    def comments = Comment.list()
    println "comments number:" + comments.size()
   
    if (m.validate()) {
    println "valid comment"
    }
    else {
    println "INVALID comment"
    }

    }
}

++++++++++++++++++++++++++++

------------- Standard Output ---------------
--Output from testSaveComment--
comments number:1
INVALID comment
------------- ---------------- ---------------

As you can see, the domain "comment" is not correct, because I've defined that its title property can not be blank, but when I add this "comment" to the "content" it is being saved into the database. But if I check if the comment is valid invoking "m.validate()" you can see that GORM know that it is not correct.

I've attached the project, so if you want you can check it.

So, please, do you know if I can solve this problem in any way?

Another question is, if I invoke the method "c.addToComments(m)", then the "comment" has to be directly saved into the database ??? I thought that I was to call explicitly the method "c.save()" in order to the "comment" were saved into the database.

Could you help me with these issues, please ???

Thank you very much in advance.



t1.zip
Reply | Threaded
Open this post in threaded view
|

Re: GORM doesn't perform validate when addTo

Peter Ledbrook
In reply to this post by jl_monteagudo
> Another question is, if I invoke the method "c.addToComments(m)", then the
> "comment" has to be directly saved into the database ??? I thought that I
> was to call explicitly the method "c.save()" in order to the "comment" were
> saved into the database.

This is a common mistake because many people are unfamiliar with the
way Hibernate works. When you do a "save()", Grails does not
immediately add the object to the database. Instead, it attaches it to
the Hibernate session. This session is basically an in-memory store of
objects that Hibernate knows about.

So why, you ask, is your comment saved? Near the end of the web
request, the Hibernate session is "flushed". What this means is that
Hibernate takes all the objects in the session and persists them to
the database. So even if you haven't called "save()" explicitly on an
object, if it's in the session it will be persisted. Actually, this
isn't quite true: Hibernate only persists objects that have actually
changed.

In your case, as soon as you call "save()" on the Content object, it
is attached to the session. Any subsequent changes to that object will
then be persisted to the database *including any comments you add*.

There is actually a very simple solution to your problem: change the
order in which you do things:

       Content c = new Content(title:"title")

       Comment m = new Comment(title:"")
       c.addToComments(m)

       c.save(flush:true)

Now "save()" will validate the Content object and its one Comment.

Hope that helps,

Peter

--
Software Engineer
G2One, Inc.
http://www.g2one.com/

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: GORM doesn't perform validate when addTo

jl_monteagudo
Thank you very much for your response, it is very clear.

In this example I was creating the "Content" on the fly, so in your example it was not still attached to the Hibernate Session.

But in my application the object of type "Content" was already in the database, so when I call to Content.get(x) then it becomes attached to the Hibernate Session, and if add to Content an invalid Comment then this comment is saved into the database.

After your explanation I have seen that I can solve this problem doing this:


def c = Content.get(1)
Comment m = new Comment(title:"")
m.content = c
m.save()


Working in this way invalid comments are not being saved into the database. Do you think that this is a good solution, or there is something that I'm missing ??


Thank you very much for your time and your help !!




Peter Ledbrook-2 wrote
> Another question is, if I invoke the method "c.addToComments(m)", then the
> "comment" has to be directly saved into the database ??? I thought that I
> was to call explicitly the method "c.save()" in order to the "comment" were
> saved into the database.

This is a common mistake because many people are unfamiliar with the
way Hibernate works. When you do a "save()", Grails does not
immediately add the object to the database. Instead, it attaches it to
the Hibernate session. This session is basically an in-memory store of
objects that Hibernate knows about.

So why, you ask, is your comment saved? Near the end of the web
request, the Hibernate session is "flushed". What this means is that
Hibernate takes all the objects in the session and persists them to
the database. So even if you haven't called "save()" explicitly on an
object, if it's in the session it will be persisted. Actually, this
isn't quite true: Hibernate only persists objects that have actually
changed.

In your case, as soon as you call "save()" on the Content object, it
is attached to the session. Any subsequent changes to that object will
then be persisted to the database *including any comments you add*.

There is actually a very simple solution to your problem: change the
order in which you do things:

       Content c = new Content(title:"title")

       Comment m = new Comment(title:"")
       c.addToComments(m)

       c.save(flush:true)

Now "save()" will validate the Content object and its one Comment.

Hope that helps,

Peter

--
Software Engineer
G2One, Inc.
http://www.g2one.com/

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email