Grails
  1. Grails
  2. GRAILS-8101

org.postgresql.util.PSQLException: No value specified for parameter 1 upon user.save()

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Critical Critical
    • Resolution: Cannot Reproduce
    • Affects Version/s: 2.0-M2
    • Fix Version/s: 2.3.5
    • Component/s: Persistence
    • Labels:
    • Environment:
      grails-2.0.0.BUILD-SNAPSHOT #1457

      Description

      Hoping to find some cues here, I copy this issue over from StackOverflow (http://stackoverflow.com/questions/7447922/):

      Upon registration to my Grails app, the user receives an email with a confirmation link. Clicking that link, takes her to the according 'enable' action.

      This worked flawlessly. However, there now seems to be an error with a very specific token, which fails the user.save() of this snippet:

      assert !user.isDirty()  // assertion is ok
      user.enabled = true
      user.confirmationToken = null
      assert user.isDirty()   // assertion is ok
      
      if (user.save()) {  // FAILS WITH ERROR BELOW
          // ...
      }
      

      Stacktrace:

      [ 16.09.2011 11:57:47.591] [http-bio-localhost/127.0.0.1-8080-exec-3] 
      ERROR 
      org.codehaus.groovy.grails.web.errors.GrailsExceptionResolver 
      org.apache.commons.logging.impl.SLF4JLog 
      
       Exception occurred when processing request: [GET] /user/enable/bc73701c-d280-4de0-8951-7af9f2a3d636
      Stacktrace follows:
      org.postgresql.util.PSQLException: No value specified for parameter 1.
              at org.postgresql.core.v3.SimpleParameterList.checkAllParametersSet(SimpleParameterList.java:178)
              at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:246)
              at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:500)
              at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:388)
              at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:273)
              at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96)
              at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96)
              at myproj.UserService.enableUser(UserService.groovy:234)
              at myproj.UserController$_closure8.doCall(UserController.groovy:244)
              at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
              at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
              at java.lang.Thread.run(Thread.java:619)
      

      Note that I can create additional users in the same running instance - but the error (so far) only occurs with that code.

      Any ideas on how to resolve that?

      Versions in use:

      PostgreSQL: 9.1beta3
      JDBC-driver: postgresql:9.1-901.jdbc4
      Grails: 2.0.0.BUILD-SNAPSHOT (Build #1457)

      (Due to being on development builds for those parts, it might be a bug, but I am unsure about that.)

      1. g8101.tar.bz2
        160 kB
        Bernhard Areich

        Activity

        Hide
        Graeme Rocher added a comment -

        can you please attach an example that reproduces the problem, or at least the SQL that is causing the issue from the logs

        Show
        Graeme Rocher added a comment - can you please attach an example that reproduces the problem, or at least the SQL that is causing the issue from the logs
        Hide
        Bernhard Areich added a comment -

        I've investigated further and found out that the error stems from validation ( validate(), as opposed to save() ) as the following fails with the mentioned error:

        User user = User.findByConfirmationToken('bc73701c-d280-4de0-8951-7af9f2a3d636')
        user.validate()
        

        Here's the according Hibernate debug output:

        Hibernate: select this_.id as id7_0_, this_.version as version7_0_, this_.account_expired as account3_7_0_, ... from "user" this_ where this_.email=?
        Hibernate: select this_.id as id7_0_, this_.version as version7_0_, this_.account_expired as account3_7_0_, ... from "user" this_ where this_.username=?
        Hibernate: select this_.id as id7_0_, this_.version as version7_0_, this_.account_expired as account3_7_0_, ... from "user" this_ where this_.username ilike ? and this_.id<>?
        Hibernate: select this_.id as id7_0_, this_.version as version7_0_, this_.account_expired as account3_7_0_, ... from "user" this_ where this_.id=?
        ["http-bio-8080"-exec-3] 10-03 11:58:06 229 ERROR org.hibernate.util.JDBCExceptionReporter | Für den Parameter 1 wurde kein Wert angegeben.

        I've now also tested with more stable versions:

        • Grails 2 revision #1468
        • PostgreSQL 8.4.8 and 9.1.0
        • JDBC: postgresql:postgresql:8.4-702.jdbc4

        The result is always the same.

        (I am having trouble to output the SQL with actual data - tried 'logSql' in DataSource.groovy and trace 'org.hibernate.sql', 'org.hibernate.type' in log4j (Config.groovy) )

        Show
        Bernhard Areich added a comment - I've investigated further and found out that the error stems from validation ( validate(), as opposed to save() ) as the following fails with the mentioned error: User user = User.findByConfirmationToken('bc73701c-d280-4de0-8951-7af9f2a3d636') user.validate() Here's the according Hibernate debug output: Hibernate: select this_.id as id7_0_, this_.version as version7_0_, this_.account_expired as account3_7_0_, ... from "user" this_ where this_.email=? Hibernate: select this_.id as id7_0_, this_.version as version7_0_, this_.account_expired as account3_7_0_, ... from "user" this_ where this_.username=? Hibernate: select this_.id as id7_0_, this_.version as version7_0_, this_.account_expired as account3_7_0_, ... from "user" this_ where this_.username ilike ? and this_.id<>? Hibernate: select this_.id as id7_0_, this_.version as version7_0_, this_.account_expired as account3_7_0_, ... from "user" this_ where this_.id=? ["http-bio-8080"-exec-3] 10-03 11:58:06 229 ERROR org.hibernate.util.JDBCExceptionReporter | Für den Parameter 1 wurde kein Wert angegeben. I've now also tested with more stable versions: Grails 2 revision #1468 PostgreSQL 8.4.8 and 9.1.0 JDBC: postgresql:postgresql:8.4-702.jdbc4 The result is always the same. (I am having trouble to output the SQL with actual data - tried 'logSql' in DataSource.groovy and trace 'org.hibernate.sql', 'org.hibernate.type' in log4j (Config.groovy) )
        Hide
        Bernhard Areich added a comment -

        I was able to track down the problem and strip it down to a minimum. Attached is a grails app that allows to reproduce the problem (g8101.tar.bz2). The relevant parts are:

        class User {
        	static hasOne	= [ acceptedInvitation: Mapping ]
        	static mappedBy	= [ acceptedInvitation: 'invitee' ]
        
        	// ...
        	static constraints = {
        		// THE EVIL:
        		acceptedInvitation	nullable: true, unique: true
        	}
        	// ...
        }
        
        class Mapping {
        	static belongsTo = [invitee:User]
        	User issuer
        }
        

        I am unaware about the actual internals, but the user.validate() seems to 'forget' to send the value (parameter #1) when checking fur uniqueness on `acceptedInvitation`. Maybe someone could explain what is actually going on here?

        Removing the unique-contraint (and placing in into the Mapping DC, if desired), resolves the issue.

        I wonder if the nullable-constraint is okay here

        By the way: The problem also occurs when H2 is used as a database (probably it's DB-independent in the first place ...).

        As I've been spending 10 hours on this topic, I'd like to ask if you could implement a noticable and understandable error message for such cases?

        See also: http://stackoverflow.com/questions/7220006/grails-hibernate-does-select-before-insert-without-passing-id-argument-value

        Show
        Bernhard Areich added a comment - I was able to track down the problem and strip it down to a minimum. Attached is a grails app that allows to reproduce the problem (g8101.tar.bz2). The relevant parts are: class User { static hasOne = [ acceptedInvitation: Mapping ] static mappedBy = [ acceptedInvitation: 'invitee' ] // ... static constraints = { // THE EVIL: acceptedInvitation nullable: true , unique: true } // ... } class Mapping { static belongsTo = [invitee:User] User issuer } I am unaware about the actual internals, but the user.validate() seems to 'forget' to send the value (parameter #1) when checking fur uniqueness on `acceptedInvitation`. Maybe someone could explain what is actually going on here? Removing the unique-contraint (and placing in into the Mapping DC, if desired), resolves the issue. I wonder if the nullable-constraint is okay here By the way: The problem also occurs when H2 is used as a database (probably it's DB-independent in the first place ...). As I've been spending 10 hours on this topic, I'd like to ask if you could implement a noticable and understandable error message for such cases? See also: http://stackoverflow.com/questions/7220006/grails-hibernate-does-select-before-insert-without-passing-id-argument-value
        Hide
        Eli Israel added a comment -

        I'm getting this as well, Graeme. Under nearly identical conditions. I've also seen online hints that there was an old bug in Hibernate that could cause this, owing to a faulty optimization in PreparedStatement.

        Perhaps time to update to Hibernate 3.6.10? Or 4.1.x? Please advise.

        Show
        Eli Israel added a comment - I'm getting this as well, Graeme. Under nearly identical conditions. I've also seen online hints that there was an old bug in Hibernate that could cause this, owing to a faulty optimization in PreparedStatement. Perhaps time to update to Hibernate 3.6.10? Or 4.1.x? Please advise.
        Hide
        Eli Israel added a comment -

        Sorry, I meant to add that I'm seeing this using MySQL, so it's definitely not PSQL-specific.

        See this Stackoverflow discussion:

        http://stackoverflow.com/questions/7290563/hibernate-exception-no-value-specified-for-parameter-2-when-running-grails-1-3

        Show
        Eli Israel added a comment - Sorry, I meant to add that I'm seeing this using MySQL, so it's definitely not PSQL-specific. See this Stackoverflow discussion: http://stackoverflow.com/questions/7290563/hibernate-exception-no-value-specified-for-parameter-2-when-running-grails-1-3
        Hide
        Eli Israel added a comment -

        Further confirmation: I found a domain class where I had unknowingly used the "unique: true, nullable: true" combination. As soon as I removed the uniqueness constraint, voila, all is working.

        Show
        Eli Israel added a comment - Further confirmation: I found a domain class where I had unknowingly used the "unique: true, nullable: true" combination. As soon as I removed the uniqueness constraint, voila, all is working.
        Hide
        Graeme Rocher added a comment -

        For the record Eli Israel's error seems a different problem to the original issue

        Show
        Graeme Rocher added a comment - For the record Eli Israel's error seems a different problem to the original issue
        Hide
        Trygve Amundsen added a comment -

        We get the exact same thing on H2 when using hasOne and unique:true.

        Show
        Trygve Amundsen added a comment - We get the exact same thing on H2 when using hasOne and unique:true.
        Hide
        Graeme Rocher added a comment -

        Burt - could you look at this one please

        Show
        Graeme Rocher added a comment - Burt - could you look at this one please
        Hide
        Jason Stonebraker added a comment -

        I can confirm that using the unique: true constraint on the parent class of a one-to-one association results in the "No value specified for parameter 1" error. Removing the unique constraint (recommended in the Grails documentation) resolves the issue.

        http://grails.org/doc/latest/guide/single.html#gormAssociation -> Example C

        Show
        Jason Stonebraker added a comment - I can confirm that using the unique: true constraint on the parent class of a one-to-one association results in the "No value specified for parameter 1" error. Removing the unique constraint (recommended in the Grails documentation) resolves the issue. http://grails.org/doc/latest/guide/single.html#gormAssociation -> Example C
        Hide
        Vladimir Havenchyk added a comment -

        Have same with grails 2.2.4 and mysql db. "No value specified for parameter 1"

        class Book

        { static belongsTo = [author: Author] }

        class Author {

        static hasOne = [book: Book]

        static constraints =

        { book(unique: true) }

        }

        Maybe it is my problem, but removing (unique: true) solves problem

        Show
        Vladimir Havenchyk added a comment - Have same with grails 2.2.4 and mysql db. "No value specified for parameter 1" class Book { static belongsTo = [author: Author] } class Author { static hasOne = [book: Book] static constraints = { book(unique: true) } } Maybe it is my problem, but removing (unique: true) solves problem
        Hide
        Graeme Rocher added a comment -

        I cannot reproduce this with the example application attached and the current version of Grails with either H2 or Postgres configured as a database

        Show
        Graeme Rocher added a comment - I cannot reproduce this with the example application attached and the current version of Grails with either H2 or Postgres configured as a database
        Hide
        Vladimir Havenchyk added a comment -

        But why closed? Graeme, should I create new ticket for this with mysql? 12 up votes, proved examples.

        Show
        Vladimir Havenchyk added a comment - But why closed? Graeme, should I create new ticket for this with mysql? 12 up votes, proved examples.

          People

          • Assignee:
            Graeme Rocher
            Reporter:
            Bernhard Areich
          • Votes:
            12 Vote for this issue
            Watchers:
            11 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:
              Last Reviewed:

              Development