Исключение гибернации «Не указано значение для параметра 2» при запуске grails 1.3.7 - PullRequest
5 голосов
/ 03 сентября 2011

У меня странная проблема с моим приложением. Приложение было разработано и протестировано с HSQLDB, и работало нормально. Когда я создал файл WAR и развернул его на сервере, один конкретный фрагмент кода (разумеется, важный для приложения) не удался.

код

def assessment = Assessment.findByPostingAndAssessor(posting, judge)

Ошибка:

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)

Я посмотрел в Google и нашел это довольно старое сообщение в блоге

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

, который ссылается на эту проблему и говорит, что она была вызвана плохой версией hibernate. Но это три года; Сейчас я использую Grails 1.3.7 с плагином hibernate 1.3.7. Кроме того, я не мог понять, где найти спецификации maven, которые описываются в блоге, чтобы я мог их редактировать.

И ни одно из моих других приложений не демонстрирует эту проблему. Я попытался использовать искатель, как описано выше, и попытался вручную создать критерий запроса, но оба вывели ту же ошибку Ни одно из значений, переданных методу, не является нулевым.

Мне действительно очень нужно, чтобы это работало КАК МОЖНО СКОРЕЕ, поэтому мне интересно, есть ли у кого-нибудь идеи о том, что попробовать дальше.

Для записи, вы можете увидеть полную трассировку стека здесь: http://grails.1312388.n4.nabble.com/file/n3787337/hibernate-exception.txt

Спасибо

Gene

ИЗД. 02.09.2011:

Вот журнал гибернации / SQL, который приводит к ошибке:

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

Далее следует трассировка стека.

ИЗД. 3.09.2011:

Вот участвующие классы:

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
}
}

Предполагаете ли вы, что иерархические отношения между Searcher и User являются частью проблемы?

Опять же, я должен подчеркнуть, что этот код работает, когда я запускаю его как приложение запуска с базой данных в памяти.

ИЗД. 3.09.2011:

Вот тестовый пример, иллюстрирующий проблему. Работает нормально как grails run-app (в памяти), но завершается неудачно, когда вы используете 'grails prod run-app` (с базой данных MySQL).

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

ИЗД. 09.04.2011: Я задал этот вопрос и группе Grails Nabble, и Даниэль Энрике Алвес Лима выявил потенциальную проблему со схемой моего кода. (См. его пост на Набл). Кажется, проблема в том, что я кодировал:

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

в моем Assessment классе, что привело к поведению, описанному выше. Когда я изменил декларацию на

    static belongsTo = [assessor: Searcher]

код findBy..() работал правильно. Я все еще думаю, что в коде скрывается ошибка гибернации (так как пропуск параметров не является хорошим способом сообщения об ошибках :-)), но по крайней мере моя программа теперь сохраняет данные!

Спасибо всем, кто внес свой вклад в решение!

Ответы [ 2 ]

1 голос
/ 03 сентября 2011

Полагаю, это потому, что один из posting или judge равен нулю.Если это не так, вы можете попробовать включить ведение журнала SQL, хотя я не уверен, произойдет ли это до или после кода, который вызывает исключение.

Добавление этого в раздел log4j в Config.groovy приведет кзарегистрируйте SQL:

debug 'org.hibernate.SQL'

, и это запишет параметры связывания:

trace 'org.hibernate.type'

Edit 9/4: Я провел некоторое время в отладчике с вашимтестовый код, и это связано с взаимно-однозначным отображением между Posting и Assessment.Один-к-одному использует то же значение для первичного ключа, что и внешний ключ владельца, поэтому в коде заполнения PreparedStatement есть логика, которая пропускает вызов для установки значения 1-го аргумента и не увеличивает счетчик позициитаким образом, одно значение, которое установлено, является значением 2-го аргумента в 1-м слоте и ничем во 2-м.Вы можете увидеть из вывода log4j, что HSQLDB делает то же самое, но он явно менее строг.Обратите внимание, что HSQLDB работает только по совпадению, так как вы создаете только один экземпляр каждого, поэтому они имеют одинаковое значение идентификатора - если вы сначала создадите несколько фиктивных экземпляров одного типа, чтобы вызвать несоответствие, вы получите неправильные результаты (но неисключение).Я предлагаю переработать его как один-ко-многим, и если вам нужно, вы можете добавить ограничение, ограничивающее размер коллекции максимум одним, например, children(size:0..1) - см. http://grails.org/doc/latest/ref/Constraints/size.html

0 голосов
/ 10 декабря 2015

При попытке найти объект по другому объекту возникнет та же ошибка с граалями 2.3.11, это обязательное поле (принадлежит ТО на месте).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...