开发者

Hibernate exception 'No value specified for parameter 2' when running grails 1.3.7

开发者 https://www.devze.com 2023-04-01 22:46 出处:网络
I am running into an odd problem with my application. The app was developed and tested with HSQLDB, and worked fine. When I built a WAR file & deployed it on a server, one particular bit of code (

I am running into an odd problem with my application. The app was developed and tested with HSQLDB, and worked fine. When I built a WAR file & deployed it on a server, one particular bit of code (crucial to the app, of course) failed.

The code

def assessment = Assessment.findByPostingAndAssessor(posting, judge)

The error:

Caused by: java.sql.SQLException: No value specified for parameter 2
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:926)
    at com.mysql.jdbc.PreparedStatement.fillSendPacket(PreparedStatement.java:2214)
    at com.mysql.jdbc.PreparedStatement.fillSendPacket(PreparedStatement.java:2138)
    at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1853)
    at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208)
    at org.hibernate.loader.Loader.getResultSet(Loader.java:1808)
    at org.hibernate.loader.Loader.doQuery(Loader.java:697)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
    at org.hibernate.loader.Loader.doList(Loader.java:2228)

I looked around on Google, and found this rather old blog post

http://blog.flurdy.com/2008/09/no-value-specified-for-parameter-when.html

which alludes to this problem and says it was caused by a bad version of hibernate. But that's three years old; I am now using grails 1.3.7 with hibernate plugin 1.3.7. Furthermore, I couldn't figure out where to find the maven specifications that the blog post describes so that I could edit them.

And none of my other apps is exhibiting this problem. I tried using the finder as above, and tried manually to create a criteria query, but both produced the same error. Neither value passed to the method is null.

I really really really need this to work ASAP, so I am wondering if anyone has any ideas of what to try next.

For the record, you can see the full stack trace here: http://grails.1312388.n4.nabble.com/file/n3787337/hibernate-exception.txt

Thanks,

Gene

EDITED 9/2/2011:

Here is the hibernate/SQL log that lead up to the error:

11/09/02 17:56:15 DEBUG hibernate.SQL: select this_.id as id22_0_, this_.version as version22_0_, this_.assessor_id as assessor3_22_0_, this_.comment as comment22_0_, this_.date_created as date5_22_0_, this_.last_updated as last6_22_0_, this_.value as value22_0_ from assessment this_ where this_.id=? and this_.assessor_id=?
11/09/02 17:56:15 TRACE type.LongType: binding '2' to parameter: 1
11/09/02 17:56:15 ERROR util.JDBCExceptionReporter: No value specified for parameter 2
11/09/02 17:56:15 ERROR docusearch.UiController: Could not save assessment
org.hibernate.exception.SQLGrammarException: could not execute query

The stack trace follows.

EDITED 9/3/2011:

Here are the classes involved:

package com.fxpal.docusearch

import com.sun.org.apache.xalan.internal.xsltc.cmdline.getopt.IllegalArgumentException;

class Assessment {
    Posting posting
    AssessmentValue value
    Searcher assessor

    static belongsTo = [posting: Posting, assessor: Searcher]

    static indexes = {
    posting()
    assessor()
    }

    static constraints = {
        posting(nullable: false)
        value()
        assessor(nullable: true)
    }

    static judge(Posting posting, Searcher judge, String value) {
        if (judge == null)
            throw new IllegalArgumentException("missing judge value");
        // error occurs here
        def assessment = Assessment.findByPostingAndAssessor(posting, judge)
        def judgment = AssessmentValue.fromString(value)
        if (judgment && !assessment)
            assessment = new Assessment( posting: posting, assessor: judge )
        if (!judgment && assessment) {
            assessment.delete(flush:true)
            assessment = null
        }
        else {
            assessment.value = judgment
            assessment.save(flush:true)
        }
        return assessment
    }
}


package com.fxpal.docusearch

class Posting {
    Document document
    int rank
    double score
    Assessment assessment

    static mapping = {
        cache true
    }

    static belongsTo = [document: Document, query: Query]
    static constraints = {
        document(nullable: false)
        rank()
        score()
        assessment(nullable: true)
    }
}


package com.fxpal.docusearch

import com.fxpal.authentication.User

class Searcher Extends User {
    String name
    String email
    String color

    static constraints = {
            name(blank:false, unique: true, maxSize:255)
        email(nullable: true)
        color(blank: false)
    }

    static mapping = {
        tablePerHierarchy true
    }

    public String displayName() {
        return name ?: username
    }
}


package com.fxpal.authentication

// This is the generic class generated by the Spring Security plugin
class User {

    String username
    String password = 'n/a'
    boolean enabled = true
    boolean accountExpired = false
    boolean accountLocked = false
    boolean passwordExpired = false

    static constraints = {
        username blank: false, unique: true
        password blank: false
    }

    static mapping = {
        password column: '`password`'
    }

    Set<Role> getAuthorities() {
    UserRole.findAllByUser(this).collect { it.role } as Set
}
}

Do you suppose the hierarchical relationship between Searcher and User is part of the problem?

Again, I should emphasize that this code works when I run it as a run-app with an in-memory database.

EDITED 9/3/2011:

Here is a test case that illustrates the problem. Runs fine as grails run-app (in memory) but fails when you use 'grails prod run-app` (with a MySQL db).

http://grails.1312388.n4.nabble.com/file/n3788449/test.zip

EDITED 9/4/2011: I had asked this question on the Grails Nabble group as well, and Daniel Henrique Alves Lima identified a potential problem with the schema of my code. (See his post on Nabble). The problem seems to be that I had coded:

    开发者_StackOverflow中文版static belongsTo = [posting: Posting, assessor: Searcher]

in my Assessment class, which resulted in the behavior described above. When I changed the declaration to

    static belongsTo = [assessor: Searcher]

the findBy..() code worked correctly. I still think there is a hibernate bug lurking in the code (as leaving out parameters is not a good way to report errors :-) ), but at least my program now saves data!

Thanks to everyone who contributed to the solution!


I assume it's because one of posting or judge is null. If that's not the case, you could try turning on SQL logging, although I'm not sure if that happens before or after the code that throws the exception.

Adding this to the log4j section in Config.groovy will log the SQL:

debug 'org.hibernate.SQL'

and this will log the bind parameters:

trace 'org.hibernate.type'

Edit 9/4: I spent some time in the debugger with your test code and it's due to the one-to-one mapping between Posting and Assessment. A one-to-one uses the same value for the primary key as the foreign key of the owner, so there's logic in the PreparedStatement population code that skips the call to set the value of the 1st arg and doesn't increment the position counter, so the one value that's set is the 2nd arg's value in the 1st slot and nothing in the 2nd. You can see from the log4j output that HSQLDB does the same thing, but it's apparently less strict. Note that HSQLDB only coincidentally works since you only create one instance of each, so they share the same value of the id - if you create some dummy instances of one type first to force a mismatch you'll get the wrong results (but not an exception). My suggestion is to rework it as a one-to-many and if you need to you can add a constraint that limits the size of the collection to at most one, e.g. children(size:0..1) - see http://grails.org/doc/latest/ref/Constraints/size.html


Have the same error with grails 2.3.11 while trying to find object by another object, that is mandatory field (belongsTO is in place).

0

精彩评论

暂无评论...
验证码 换一张
取 消