Grails: порядок сортировки для отношений один-ко-многим не работает - PullRequest
2 голосов
/ 26 марта 2012

У меня есть простое двунаправленное отображение «один ко многим», как показано ниже, с порядком сортировки по умолчанию, указанным на стороне владельца.Тем не менее, порядок сортировки, кажется, не применяется?Я использую Grails v2.0.1 (сейчас я скопировал этот пример с v1.3.7).

package playground

class User {

    String name

    static hasMany = [ posts : Post ]

    static mapping = {
        posts sort:'position'
    }
}

и

package playground

class Post {

    int position = 1
    String message

    static belongsTo = [ user : User ]
}

. Это код интеграционного теста.используя для этого упражнения ...

    def User user = new User(name:'bob')
    user.addToPosts(new Post(position:2, message:'two'))
    user.addToPosts(new Post(position:3, message:'three'))
    user.addToPosts(new Post(position:1, message:'one'))

    assertTrue user.validate()
    assertFalse user.hasErrors()
    assertNotNull user.save()

    for (post in user.posts) {
        log.debug "Post message> ${post.message}"
    }

Пожалуйста, избавь меня от моих страданий, это, по-видимому, что-то очевидное, но я не вижу этого!Благодаря.

Ответы [ 4 ]

7 голосов
/ 11 июня 2012

используйте этот код:

package playground

    class User {

        String name
        static hasMany = [ posts : Post ]

        static mapping = {
            posts sort:'position' order:'desc'//order:'asc'
        }
    }
1 голос
/ 05 апреля 2012

Оказывается, это немного странное поведение в крайнем случае, это действительно результат написания теста.По сути, все происходит в рамках одного сеанса Hibernate / txn (см. Выше).Таким образом, тест извлекает только что созданный граф объектов (с установленным не по порядку), а не извлекает данные из базы.и «заказ по» работает, как ожидалось.Например,

User.withNewSession{ session ->
   def User foundUser = User.get(user.id);

   for (post in foundUser.posts) {
      println "Post message> ${post.message}"
   }
}

Код предоставлен ndtreviv.

0 голосов
/ 12 февраля 2017

Ответ Оуэнса избавил меня от путаницы, в которой я находился. Я пытался установить порядок, определенный для отношений между пользователями (1) и постами (многими), но когда я писал начальные тесты, они терпели неудачу, используя пользователя .get (u.id) был в том же сеансе - и поэтому просто читал из кеша, и они возвращались в том порядке, в котором я написал, что сначала они не самые новые, как я ожидал.

Затем я переписал тест для двух сессий и low, и вот во второй сессии на этот раз вернул посты в порядке убывания.

Так что вам просто нужно быть осторожным. если вы находитесь в том же исходном сеансе, где создаются сообщения, вам необходимо использовать User.get (u.id) .posts.sort ().

Все эти маленькие ошибки, не понимающие должным образом, как кэш сеанса и базовая БД работают в рамках одной и той же сессии / транзакции. иногда болит мозг.

пока мы отмечаем некоторые вещи - это ошибка в интеграционном тесте в 3.2.5, но я заметил нить Джеффа и исправление, которое исчезло. Итак, я обновился до версии Grails 3.2.6 прошлой ночью, и этот тест теперь работает

void "test query"() {
    given:"a user and where query for users, and posts "
    User u

    when: "create a post for user "
    User.withNewSession { session ->
        u = new User(username: 'will')
        u.save(flush: true, failOnError: true)
        Post p1 = new Post(comment: [food: "bought coffee and cake "])
        Post p2 = new Post(comment: [dinner: "bought wine and dinner"])
        Post p3 = new Post(comment: [view: "spectacular view of lake and sunset"])
        u.addToPosts(p1)
        u.addToPosts(p2)
        u.addToPosts(p3)
        u.save(flush: true)
        if (u.hasErrors())
            println "error saving posts on user u : ${u.errors}"


        def postList = User.get(u.id).posts
        postList.each { println "query via user.list using same session > $it.dateCreated : $it.comment" }

        Post.findAll().each { println "query via Post using same session > $it.dateCreated : $it.comment" }
    }
    //because still in same session it just returns the order from the 1st level cache - so force a
    //new session and let the DB do the sort
    def lookupPosts
    User.withNewSession{ session ->
        User uNew  = User.get(1)
        assert uNew
        lookupPosts = uNew.posts

        lookupPosts.each {println "query via user in new session > $it.dateCreated : $it.comment" }
    }



    then: " check post was added"
    !u.hasErrors ()
    lookupPosts.size() == 3
    lookupPosts[1].comment.dinner == "bought wine and dinner"

}
0 голосов
/ 27 марта 2012

Если вы используете список вместо набора (по умолчанию), фреймворк будет поддерживать для вас порядок.

List posts = new ArrayList()
static hasMany = [ posts : Post ]
...