Grails将Set中的多对一更改为List(列需要更改)

时间:2013-06-03 22:39:15

标签: hibernate grails

在Grails域对象中,我正在尝试更改域对象

class Example {
    String name

    static hasMany = [objs:DomainObject]
}

class Example {
    String name
    List objs

    static hasMany = [objs:DomainObject]
}

我收到此错误。

ERROR errors.GrailsExceptionResolver  - HibernateException occurred when processing request: [GET] /path/path
null index column for collection: com.XXXX. Stacktrace follows:
     org.hibernate.HibernateException: null index column for collection: com.XXXXXX
    at grails.converters.JSON.value(JSON.java:174)
    at grails.converters.JSON.convertAnother(JSON.java:162)
    at grails.converters.JSON.value(JSON.java:199)
    at grails.converters.JSON.convertAnother(JSON.java:162)
    at grails.converters.JSON.value(JSON.java:199)
    at grails.converters.JSON.convertAnother(JSON.java:162)
    at grails.converters.JSON.value(JSON.java:199)
    at grails.converters.JSON.convertAnother(JSON.java:162)
    at grails.converters.JSON.value(JSON.java:199)
    at grails.converters.JSON.render(JSON.java:134)
    at grails.converters.JSON.render(JSON.java:150)
    at com.XXXXController.Method(XXXXController.groovy:161)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:722)`

这在生产服务器上发生。我无法从数据库中删除任何内容,但我可以填写空列。在引导程序中我需要做什么才能修复或更改当前数据库中的数据?

4 个答案:

答案 0 :(得分:2)

看看这篇文章。它描述了如何将随机顺序放在新的idx列中。

http://tech.coterie.com/2012/11/migrating-from-set-to-list-in-grails.html

以下是文章中提供的示例SQL:

insert into user_product(user_products_id, product_id, products_idx)
select t.user_id, t.product_id, (@rownum:=@rownum+1) % c.loves AS idx
from (
    select user_id, product_id
    from love_link
    order by user_id
) t,
(
    select user_id, count(*) as loves
    from love_link
    group by user_id
) c,
(SELECT @rownum:=0) r
where c.user_id=t.user_id
order by t.user_id;

答案 1 :(得分:0)

看看Lists of Objects。您需要更改添加关联的方式。从摘录中强调下面的例子。

一瞥:

// This won't work!
def book = new Book(title: 'The Shining')
book.save()
author.addToBooks(book)

// Do it this way instead.
def book = new Book(title: 'Misery')
author.addToBooks(book)
author.save()

答案 2 :(得分:0)

当您将实例保存为下一个实例时会发生此错误,假设我们在聊天中有一个用户列表,并且我们想要将用户添加到聊天中(如组):

class ChatUserService {

    def addUserToChat(User user, Chat chat) {
        ChatUser chatUser = new ChatUser()
        chatUser.user = user
        chatUser.chat = chat // set the parent in the child
        if (!chatUser.save()) {
            throw new SaveDomainException(chatUser)
        }
    }
}

如果您在hasMany属性中声明列表,则此方法可以正常工作。

在另一种情况下,您需要将其添加到父级,并保存父级以将索引存储为下一个:

class ChatUserService {

    def addUserToChat(User user, Chat chat) {
        ChatUser chatUser = new ChatUser()
        chatUser.user = user
        chatUser.chat = chat
        chat.addToUsers(chatUser) // add the child to the parent
        if (!chat.save()) {
            throw new SaveDomainException(chatUser)
        }
    }
}

答案 3 :(得分:0)

以MYSQL为例:假设您已将用户和汽车域定义为一对多关系:

class User {
    String name;
    // List cars;
    static hasMany = [cars: Car]
}

Class Car {
    String regNum;
    static belongsTo = [user: User]
}

在更改与List之间的关系之前,数据库表Car将类似于:

|领域|输入|空|钥匙|默认|额外|

| id | bigint(20)|没有| PRI | NULL | auto_increment |

| regNum | varchar(255)|是的| | NULL | |

据我所知,如果你要改变List的多对一关系,Hibernate会在表格中创建一个car_idx列。

|领域|输入|空|钥匙|默认|额外|

...

| car_idx | int(11)|是的| | NULL | |

如果在更改之前有一些数据,默认情况下car_idx将设置为NULL,这是根本原因。

因此,您可以运行脚本在idx上设置默认值来解决此问题。