Quantcast

removeFrom not working on integration test

classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

removeFrom not working on integration test

Maricel
I have a domain object that has a one-to-many relation to another object. Something like a Store hasMany Products and Product belongsTo Store.

In the controller, I have a method that removes a product from a Store, so i have something like this:

Store store = Store.get(params.id)
Product product = Product.get(params.productId)
...
store.removeFromProducts(product)
product.delete(flush:true)
store.save(flush:true)

Running the application, when I test this method, it works perfectly. However, when I try to test it in an integration test, I get the following error message:

deleted object would be re-saved by cascade (remove deleted object from associations): [Product#100]; nested exception is org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade


Debugging the code in the integration test, after calling removeFrom I see that the product is still in the list of products of the Store object. Debugging when running the application, after calling removeFrom I can see that the product was removed from list of products.

Any ideas? Do you think this could be a bug?

Thanks!
- Maricel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

RE: re[grails-user] moveFrom not working on integration test

msmyers
why are you flushing twice? And why can't you just say product.delete instead of loading the association parent from the db, shouldn't hibernate remove it from the collection automatically?

-----Original Message-----
From: Maricel [mailto:[hidden email]]
Sent: Monday, August 17, 2009 6:16 PM
To: [hidden email]
Subject: [grails-user] re[grails-user] moveFrom not working on integration test


I have a domain object that has a one-to-many relation to another object.
Something like a Store hasMany Products and Product belongsTo Store.

In the controller, I have a method that removes a product from a Store, so i
have something like this:

Store store = Store.get(params.id)
Product product = Product.get(params.productId)
...
store.removeFromProducts(product)
product.delete(flush:true)
store.save(flush:true)

Running the application, when I test this method, it works perfectly.
However, when I try to test it in an integration test, I get the following
error message:

deleted object would be re-saved by cascade (remove deleted object from
associations): [Product#100]; nested exception is
org.hibernate.ObjectDeletedException: deleted object would be re-saved by
cascade


Debugging the code in the integration test, after calling removeFrom I see
that the product is still in the list of products of the Store object.
Debugging when running the application, after calling removeFrom I can see
that the product was removed from list of products.

Any ideas? Do you think this could be a bug?

Thanks!
--
View this message in context: http://www.nabble.com/removeFrom-not-working-on-integration-test-tp25016774p25016774.html
Sent from the grails - user mailing list archive at Nabble.com.


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

    http://xircles.codehaus.org/manage_email



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

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

RE: re[grails-user] moveFrom not working on integration test

Maricel
I flush it twice as test to see if it works, but even though I just do:

product.delete
store.save(flush:true)

it doesn't work either. If I just do product.delete, that does not remove the association, neither if I just do store.removeFromProducts(product) without calling product.delete().

As far as I know, I need to remove the association first, using removeFrom and then delete the object. I read this in some forum (I cannot seem to find it right now), but anyway it works when running the application, it is in the integration test that it doesn't do anything, which is inconsistent.

msmyers wrote
why are you flushing twice? And why can't you just say product.delete instead of loading the association parent from the db, shouldn't hibernate remove it from the collection automatically?

-----Original Message-----
From: Maricel [mailto:mquesada@backcountry.com]
Sent: Monday, August 17, 2009 6:16 PM
To: user@grails.codehaus.org
Subject: [grails-user] re[grails-user] moveFrom not working on integration test


I have a domain object that has a one-to-many relation to another object.
Something like a Store hasMany Products and Product belongsTo Store.

In the controller, I have a method that removes a product from a Store, so i
have something like this:

Store store = Store.get(params.id)
Product product = Product.get(params.productId)
...
store.removeFromProducts(product)
product.delete(flush:true)
store.save(flush:true)

Running the application, when I test this method, it works perfectly.
However, when I try to test it in an integration test, I get the following
error message:

deleted object would be re-saved by cascade (remove deleted object from
associations): [Product#100]; nested exception is
org.hibernate.ObjectDeletedException: deleted object would be re-saved by
cascade


Debugging the code in the integration test, after calling removeFrom I see
that the product is still in the list of products of the Store object.
Debugging when running the application, after calling removeFrom I can see
that the product was removed from list of products.

Any ideas? Do you think this could be a bug?

Thanks!
--
View this message in context: http://www.nabble.com/removeFrom-not-working-on-integration-test-tp25016774p25016774.html
Sent from the grails - user mailing list archive at Nabble.com.


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

    http://xircles.codehaus.org/manage_email



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

    http://xircles.codehaus.org/manage_email

- Maricel
sub
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

RE: re[grails-user] moveFrom not working on integration test

sub
I have a similar problem ... removeFrom works inside BootStrap.groovy but the exact code does not work in a controller. Have you worked out what the problem was?
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

RE: re[grails-user] moveFrom not working on integration test

Maricel
It works fine in the controller when the application is running normally, but when testing the controller method that calls the removeFrom in an integration test, it doesn't work, not even with Grails 1.2
- Maricel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

RE: re[grails-user] moveFrom not working on integration test

werner5471
Have you found an answer to your question in the meantime?

I also experienced that an integration test obviously behaves differently than a controller even though the same methods are called... see http://n4.nabble.com/belongsTo-hasMany-addTo-removeTo-test-vs-production-td1744938.html#a1744938 for example where I didn't get any replies unfortunately.

I suspect something in relation with GORM / Hibernate that behaves differently when called from a controller, e.g. in the chapter about GORM in the book "Grails 1.2" by Graeme Rocher and Jeff Brown it says that before executing a controller action, grails binds a new Hibernate session to the current thread and when it's ended and no exception was thrown the state of the session is synchronized with the DB. But actually I'm not sure why this should cause the stated different behaviours in integration tests.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

RE: re[grails-user] moveFrom not working on integration test

Maricel
I am using Grails 1.3.1 and  still have the same issue! No idea how to fix it or work around it!
- Maricel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

RE: re[grails-user] moveFrom not working on integration test

werner5471
In the meantime I've created an issue for what I think addresses that problem: https://cvs.codehaus.org/browse/GRAILS-6356

If you experience the same, just vote for it! :-]
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

RE: re[grails-user] moveFrom not working on integration test

burtbeckwith
This fails in a controller too. addTo does three things - it initializes the collection if it's null, adds the instance to the collection, and sets the instance's back-reference to the owner. It's how you work with one-to-many and many-to-many relationships in Grails.

If you put the same code in a controller it also throws a NPE:

   def someAction = {
      def parent = new Parent(parentName:'parent').save(flush:true)
      def child = new Child(childName:'child', parent:parent).save(flush:true)
      // parent.addToChildren(child); // Without this line, Exception is thrown is assertion (children is null)
      println parent.children.size()
      render 'ok'
   }

Burt

>
> In the meantime I've created an issue for what I think addresses that
> problem:  https://cvs.codehaus.org/browse/GRAILS-6356
> https://cvs.codehaus.org/browse/GRAILS-6356 
>
> If you experience the same, just vote for it! :-]
>

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

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

RE: re[grails-user] moveFrom not working on integration test

werner5471
Just re-opened the issue, because when using the scaffolded controller and saving a child with a parent, "println childInstance.parent.children.size();" returns 1 although no addTo is called anywhere:

def save = {
        def childInstance = new Child(params)
        if (childInstance.save(flush: true)) {
            flash.message = "${message(code: 'default.created.message', args: [message(code: 'child.label', default: 'Child'), childInstance.id])}"
            println childInstance.parent.children.size();
            redirect(action: "show", id: childInstance.id)
        }
        else {
            render(view: "create", model: [childInstance: childInstance])
        }
    }
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

RE: re[grails-user] moveFrom not working on integration test

burtbeckwith
Again, you need to compare apples to apples. This equivalent integration test also passes:

   class ParentChildTests extends GroovyTestCase {

      def sessionFactory

      void testParentChild() {

         def parent = new Parent(parentName:'parent').save(flush:true)
         sessionFactory.currentSession.clear() // simulate separate requests

         // fake out the form submission with proper values
         def params = [:]
         params."parent.id" = parent.id
         params.childName = 'child'

         def childInstance = new Child(params)
         childInstance.save(flush: true)
         assertEquals 1, childInstance.parent.children.size()
      }
   }

It works because under the hood, the data binding (triggered by the Map constructor, new Child(params)) calls addTo.

Burt

>
> Just re-opened the issue, because when using the scaffolded controller and
> saving a child with a parent, "println
> childInstance.parent.children.size();" returns 1 although no addTo is called
> anywhere:
>
> def save = {
>         def childInstance = new Child(params)
>         if (childInstance.save(flush: true)) {
>             flash.message = "${message(code: 'default.created.message',
> args: [message(code: 'child.label', default: 'Child'), childInstance.id])}"
>    println childInstance.parent.children.size();
>             redirect(action: "show", id: childInstance.id)
>         }
>         else {
>             render(view: "create", model: [childInstance: childInstance])
>         }
>     }
>
>

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

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

RE: re[grails-user] moveFrom not working on integration test

werner5471
Thanks, finally got an insight on that. I think this "under the hood" should be documented somewhere in the reference documentation - e.g. here and/or here.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

RE: re[grails-user] moveFrom not working on integration test

werner5471
After some further testing, I saw that the following also works (not using a Map):

    void testParentChild2() {
         def parent = new Parent(parentName:'parent').save(flush:true)
         sessionFactory.currentSession.clear() // simulate separate requests
         def childInstance = new Child(parent:parent, childName:'child').save(flush:true)
         assertEquals 1, childInstance.parent.children.size()
      }

So the only thing that seems to make the difference here is clearing the session (if commented out, the test fails). How can that be explained in relation to GORM?
Loading...