2

在 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

4 回答 4

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;
于 2013-12-05T05:40:18.203 回答
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()
于 2013-06-03T23:25:48.247 回答
0

以 MYSQL 为例:假设您已将域 User 和 Car 定义为一对多关系:

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

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

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

| 领域 | 类型 | 空 | 钥匙 | 默认 | 额外 |

| 编号 | 大整数(20) | 否 | 优先级 | 空 | 自动增量 |

| 注册号 | varchar(255) | 是 | | 空 | |

据我所知,如果您要更改与 List 的多对一关系,Hibernate 将在表中创建一个 car_idx 列。

| 领域 | 类型 | 空 | 钥匙 | 默认 | 额外 |

...

| car_idx | 整数(11) | 是 | | 空 | |

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

所以你可以运行一个脚本来设置 idx 的默认值来解决这个问题。

于 2018-04-17T11:58:55.293 回答
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)
        }
    }
}
于 2017-10-04T04:43:37.543 回答