[Grails] grails中关于一对多的映射关系(save-update)

Fly_m 2008-02-26

我现在尝试一个关于一对多的映射,在看了教程上的关于1对多的映射关系之后并按照教程上的例子试了下.发现下面一个问题.

我做的例子是一个关于新闻的例子,其中涉及到两个模型:category(目录)和article(文章).对应关系应该是一个category下应该有多个article,而一个article应该持有一个category.我现在要实现的就是在删除category时不会删除其下的article,按照教程上的例子来看有如下代码:

 

class Category {

String name;
static hasMany = [articles:Article]
}
和Article类
class Article {
String name;
}

按照这样默认的映射关系,grails会创建三个表,一个category,一个article和一个category_article表,其中category_article表保存二者的映射关系.这样可以实现在删除category时不会删除article是一种默认的save-update模式.但是按照这样的映射关系,在article中并没有持有category这个对象,即无法得到article所属的category.于是改写article类,增加一个category的持久对象,将article改为

 

class Article{

String name
Category category
}

 这样运行时,当删除category时,会出现一个约束异常,意思好像是外键约束导致不能删除category.再将category中的

static hasMany = [articles:Article]删去,结果仍然是这样.

那么现在在article中加入belongsTo标签,

static belongsTo = Category 或者static belonsTo = [category:Category]

这两种情况下,出现的结果都是级联删除,在教程上有这样一句话

 

写道
The default cascading behaviour is to cascade saves and updates, but not deletes unless a belongsTo is also specified:

  意思难道是如果这belongsTo这个标签,那么关联关系肯定就是delete了吗?

我参照http://grails.group.iteye.com/group/blog/163911 上写的关于级联的例子并运行之,发现它的例子实现的效果仍然是delete,即使在mapping中将category的cascade属性写为save-update或者none,或者将articles属性写成save-update,none,仍然不起作用,只要在这个belonsTo这个属性存在,它实现的好像都是delete操作.弄了很久,都没有办法实现save-update操作.

不知道各位有什么好的建议,我只实现一个关于一对多的例子,要求多的这方能够得到一这方的一个引用.现在的问题就是一这方能够有多这方的引用,但是多这方没有一这方的引用,且实现的级联策略为save-update(不是delete),请各位给我看看,谢谢了.

 

Fly_m 2008-02-26
编辑有点乱,还请原谅.
agile_boy 2008-02-26
将你的工程打包一下,上传过来,我看看
Fly_m 2008-02-26
东西已经发到你的站内信上了,请查收一下.:)
lidg 2008-02-27
我想象你这样的需求估计只用配置是不能实现的,你得1.保证数据表没有FOREIGN KEY 要不然数据库是不让删除存在子目录的目录的;2.在你做删除时要自己update它的子目录。这样配置一对多:parent:[column:'parent_Id',lazy:"true",cascade:"none"]不用belongsTo;
去掉数据表中:FOREIGN KEY (`parent_id`) REFERENCES `system_menu` (`id`)的约束;在delete目录前update它的子目录的parent_id为空。
agile_boy 2008-02-28
我想要删除category的话,先将set清空再save,然后再delete呢?当然最好不要加belongTo。
Fly_m 2008-02-28
我昨天想了下,这是这样实现的,在parent里加了一个beforeDelete的属性
代码如下:
def beforeDelete = {
articles.each{
  removeFromArticles(it)
}
}
不知道这样的效果行不,但这样的运行效果是出来了.
上面两位说到的不用belongsTo,因为从grails自己生成的表来看,它是在article表中加了约束的,所以,为了不影响这个约束,我就加了上面一句话.
根据 lidg 的说法,这样在删除之前先更新article类.
left 2008-02-28
去看文档?
casephoen 2008-03-24
Java代码
class Category {  
<BR>    String name;  
<BR>    static hasMany = [articles:Article]  
<BR>}  
<BR>和Article类  
<BR>class Article {  
<BR>    String name;  
<BR>} 

class Category {
String name;
static hasMany = [articles:Article]
}
和Article类
class Article {
String name;
}按照这样默认的映射关系,grails会创建三个表,一个category,一个article和一个category_article表,其中category_article表保存二者的映射关系.这样可以实现在删除category时不会删除article是一种默认的save-update模式.

-----兄弟,就是这样子的,要想不级联删除,必须用中间表,因为表是根据你的class生成的,如果你在article加上一个Category属性,就没有中间表了。你可以通过article对象得到category_id,然后category.find(id);或者你创建一个对应中间表的class应该可以解决


Global site tag (gtag.js) - Google Analytics