在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)`
这在生产服务器上发生。我无法从数据库中删除任何内容,但我可以填写空列。在引导程序中我需要做什么才能修复或更改当前数据库中的数据?
答案 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上设置默认值来解决此问题。