Grails
  1. Grails
  2. GRAILS-8972

Domain constructor taking map of values fails to create associations and lists

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Blocker Blocker
    • Resolution: Fixed
    • Affects Version/s: 2.0.2
    • Fix Version/s: 2.0.3
    • Component/s: Persistence
    • Labels:
      None
    • Environment:
      java 1.6 running amazon aws stock beanstalk config, 64bit m1.small instance.

      Description

      I have domain objects in Grails 2.0.1 that are created and saved with the following syntax:

      // nickname is a string
      def acct = session.get('account')
      def site = new Site(account: acct, nickname: nickname, subItems: [])

      in grails 2.0.2 the following has become broken...
      In the site object... subItems list is null, and the account instance is null; though null was not passed in for either.
      subItems was a simple (non persistent) list. Account is a persistent object though pulled from http session so it is detached.

        Issue Links

          Activity

          Hide
          Graeme Rocher added a comment -

          Grails 2.0.2 introduces implicit white lists to increase security. Can you please set bindable:true on the properties that are not binding. See:

          http://grails.org/doc/2.0.2/ref/Constraints/bindable.html

          Show
          Graeme Rocher added a comment - Grails 2.0.2 introduces implicit white lists to increase security. Can you please set bindable:true on the properties that are not binding. See: http://grails.org/doc/2.0.2/ref/Constraints/bindable.html
          Hide
          John Hayward added a comment - - edited

          That's almost certainly what's going on. I'll give it a try and see how that works.

          If that's the case; 2.0.2 is not backwards compatible with existing domain models and functionality. It's fine, but probably worth noting in the documentation that this is an incompatible change for current map constructors.

          The documentation for bindable states:
          "Properties which are not bindable by default are those related to transient fields, dynamically typed properties and static properties."

          In this case I have a parent child relationship that meets none of those criteria, but it is still not bindable by default. The parent relationship is in fact statically typed, non static, and non-transient. Seems like it's still a bug. Perhaps the documentation should be updated to include all gorm relationships are not bindable by default, or relationships should in fact be bindable by default.

          Show
          John Hayward added a comment - - edited That's almost certainly what's going on. I'll give it a try and see how that works. If that's the case; 2.0.2 is not backwards compatible with existing domain models and functionality. It's fine, but probably worth noting in the documentation that this is an incompatible change for current map constructors. The documentation for bindable states: "Properties which are not bindable by default are those related to transient fields, dynamically typed properties and static properties." In this case I have a parent child relationship that meets none of those criteria, but it is still not bindable by default. The parent relationship is in fact statically typed, non static, and non-transient. Seems like it's still a bug. Perhaps the documentation should be updated to include all gorm relationships are not bindable by default, or relationships should in fact be bindable by default.
          Hide
          Jon Palmer added a comment -

          I hit this problem too. My case was something like this:

           
          class Book {
          
            static hasOne [
              author: Author
            ]
          }
          

          in grails 2.0.1 the following constructor worked. new Book(author: myAuthor)

          but that now breaks in 2.0.2

          Another work around is to explicitly declare the property

          class Book {
          
            Author author
          
            static hasOne [
              author: Author
            ]
          }
          
          Show
          Jon Palmer added a comment - I hit this problem too. My case was something like this: class Book { static hasOne [ author: Author ] } in grails 2.0.1 the following constructor worked. new Book(author: myAuthor) but that now breaks in 2.0.2 Another work around is to explicitly declare the property class Book { Author author static hasOne [ author: Author ] }
          Hide
          Graeme Rocher added a comment -

          You can also do:

          class Book {
          
            static hasOne [
              author: Author
            ]
          
            static constraints = {
               author bindable:true
            }
          }
          
          Show
          Graeme Rocher added a comment - You can also do: class Book { static hasOne [ author: Author ] static constraints = { author bindable: true } }
          Hide
          Mathieu Perez added a comment -

          Totally agree with John Hayward. We can not upgrade to Grails 2.0.2 until we know if this is a bug or not. This is a real breaking change.

          Show
          Mathieu Perez added a comment - Totally agree with John Hayward. We can not upgrade to Grails 2.0.2 until we know if this is a bug or not. This is a real breaking change.
          Hide
          Alberto Vilches added a comment -

          It will be nice if this feature could be enabled or disabled globally with a configuration property like "grails.gorm.bindable"

          Show
          Alberto Vilches added a comment - It will be nice if this feature could be enabled or disabled globally with a configuration property like "grails.gorm.bindable"
          Hide
          Graeme Rocher added a comment -

          Alberto/Mathieu - Yeah sorry, in retrospect it was too aggressive a change to make associations not bindable by default without "bindable: true". We will put out a quick 2.0.3 to correct the problem.

          Show
          Graeme Rocher added a comment - Alberto/Mathieu - Yeah sorry, in retrospect it was too aggressive a change to make associations not bindable by default without "bindable: true". We will put out a quick 2.0.3 to correct the problem.
          Hide
          Dan Polites added a comment -

          I can't bind Maps in Grails 2.0.3 with or without bindable:true. I have to explicitly set the map on the object. We are using the mongo plugin, so we use Maps frequently. Is there something else that I need to do?

          Show
          Dan Polites added a comment - I can't bind Maps in Grails 2.0.3 with or without bindable:true. I have to explicitly set the map on the object. We are using the mongo plugin, so we use Maps frequently. Is there something else that I need to do?
          Hide
          Brian Saville added a comment -

          @Dan, I found that we had the same problem on upgrading to grails 2.0.1 from 1.3.7. I think it is change in the implicit constructor of groovy actually, and not a grails specific problem.

          Show
          Brian Saville added a comment - @Dan, I found that we had the same problem on upgrading to grails 2.0.1 from 1.3.7. I think it is change in the implicit constructor of groovy actually, and not a grails specific problem.
          Hide
          Erik Pragt added a comment -

          @Brian and @Dan
          I have the same problem here in 2.0.3. A lot of our unit tests depend on this behavior, and rewriting all of them (around 500) would be very timeconsuming.

                  Customer customer = new Customer(
                          payment: new Payment(
                                  accountNumber: "1234567",
                                  payer: new Person(
                                          surname: "Payer"
                                  )),
                          person: new Person(
                                  surname: "Person"
                          )
                  )
          

          This works in Grails 1.3.x, but in Grails 2.0.3, the person is filled, but the payment is null. Changing the sequence doesn't have any effect, and the only difference so far I could find was that Person is a domain object, while Payment isn't.

          However, I still have the same problem Dan has, and I don't think this bug is fixed. If there's any way I can help, or provide more information, please let me know.

          Show
          Erik Pragt added a comment - @Brian and @Dan I have the same problem here in 2.0.3. A lot of our unit tests depend on this behavior, and rewriting all of them (around 500) would be very timeconsuming. Customer customer = new Customer( payment: new Payment( accountNumber: "1234567", payer: new Person( surname: "Payer" )), person: new Person( surname: "Person" ) ) This works in Grails 1.3.x, but in Grails 2.0.3, the person is filled, but the payment is null. Changing the sequence doesn't have any effect, and the only difference so far I could find was that Person is a domain object, while Payment isn't. However, I still have the same problem Dan has, and I don't think this bug is fixed. If there's any way I can help, or provide more information, please let me know.
          Hide
          Trevor Samaroo added a comment -

          I'm getting this with 2.0.3 as well. transient domain properties cannot be set in the Domain objects constructor. this is causing my app to null pointer unless i re-code how i construct domain objects. is there a workaround?

          thanks.

          Show
          Trevor Samaroo added a comment - I'm getting this with 2.0.3 as well. transient domain properties cannot be set in the Domain objects constructor. this is causing my app to null pointer unless i re-code how i construct domain objects. is there a workaround? thanks.
          Hide
          Rodrigo Rosenfeld Rosas added a comment -

          @Trevor, take a look at this related reported bug:

          http://jira.grails.org/browse/GRAILS-9098

          Unfortunately it was marked as "won't fix", but I guess you can set your transient properties as bindable as a workaround.

          Show
          Rodrigo Rosenfeld Rosas added a comment - @Trevor, take a look at this related reported bug: http://jira.grails.org/browse/GRAILS-9098 Unfortunately it was marked as "won't fix", but I guess you can set your transient properties as bindable as a workaround.
          Hide
          Harald L added a comment -

          I have still the same problem and the property isn't transient...

          class FieldDefinition

          { String fieldName FieldComparator fieldComperator Object fieldValue Object fieldValueBetweenRightBoundary }

          def x = new FieldDefinition( fieldName: "quantity", fieldComperator: FieldComparator.GREATER, fieldValue: 3.0 )

          will lead into that the x.fieldValue is null.
          I'm using Grails 2.1.4 and java version "1.6.0_45"

          Show
          Harald L added a comment - I have still the same problem and the property isn't transient... class FieldDefinition { String fieldName FieldComparator fieldComperator Object fieldValue Object fieldValueBetweenRightBoundary } def x = new FieldDefinition( fieldName: "quantity", fieldComperator: FieldComparator.GREATER, fieldValue: 3.0 ) will lead into that the x.fieldValue is null. I'm using Grails 2.1.4 and java version "1.6.0_45"
          Hide
          Jeff Scott Brown added a comment -

          Harald,

          Your fieldValue is not statically typed. Only statically typed properties which are not transient and not static are bindable by default. In order for fieldValue to be bindable it needs to be configued with bindable: true, or you need to assign the value explicitly like this:

          x.fieldValue = 3.0
          
          Show
          Jeff Scott Brown added a comment - Harald, Your fieldValue is not statically typed. Only statically typed properties which are not transient and not static are bindable by default. In order for fieldValue to be bindable it needs to be configued with bindable: true, or you need to assign the value explicitly like this: x.fieldValue = 3.0
          Hide
          Harald L added a comment -

          First off all I'm impressed of the response time! Many thanks for it.
          And you are right, after configuring the Object property as bindable true it was working.
          Many thanks

          Show
          Harald L added a comment - First off all I'm impressed of the response time! Many thanks for it. And you are right, after configuring the Object property as bindable true it was working. Many thanks

            People

            • Assignee:
              Graeme Rocher
              Reporter:
              John Hayward
            • Votes:
              5 Vote for this issue
              Watchers:
              12 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development