嵌入式子类的约束 - Grails,GORM,Mongo

时间:2014-11-18 12:14:34

标签: mongodb grails constraints gorm

我已经用这个问题把头发拉了几天。

我有一个带有几个指定约束的嵌入式子类。我的问题是这些约束永远不会被强制执行, 我正在使用grails 2.3.11和mongodb插件3.0.2。

这是我的设置(稍微简化)。

媒体课

class Media{
ObjectId id;
String name;
Film film;

static mapWith = "mongo"
static embedded = ["film"]
}

电影课

class Film{
ObjectId id;
String name;

static mapWith = "mongo"
static belongsTo = [media : Media]
static mapping = {
    lazy:false
}
static constraints = {
name(nullable:false) //works as expected. Save fails if name is set to null
}
}

ActionFilm Class

class ActionFilm extends Film{
int score;
String director;

//These constraints are never enforeced. No matter what value I set the fields to the save is always successful
static constraints = {
score(min:50) 
director(nullable:true)
}
}

这是Mongo和Gorm的问题吗?是否有可能在父母和子类的bth中有约束?

保存时的示例代码

public boolean saveMedia(){
ActionFilm film = new ActionFilm()
film.setName("TRON");
film.setScore(2)
film.setDirector("Ted")

Media media = new Media()
media.setName("myMedia")
media.setFilm(film)
media.save(flush:true, failOnError:false)  //Saves successfully when it shouldn't as the score is below the minimum constrains

}

修改 我已经玩了更多的问题,只有当我用ActionFilm作为嵌入对象保存Media对象时,问题仍然存在。如果我保存ActionFilm对象,则应用验证。

 ActionFilm film = new ActionFilm()
    film.setName("TRON");
    film.setScore(2)
    film.setDirector("Ted")
    film.save(flush:true, failOnError:false)  //Doesn't save as the diameter is wrong. Expected behaviour.

因此,当我保存ActionFilm对象时,约束将按预期应用,但如果是嵌入对象则不应用约束。

1 个答案:

答案 0 :(得分:1)

我已经解决了我的问题,以防其他人遇到这个问题。它可能不是最佳解决方案,但我还没有找到替代方案。

我已经在Media类中添加了一个自定义验证器,它在嵌入式Film类上调用validate()并添加了Media对象错误中出现的任何错误

class Media{
ObjectId id;
String name;
Film film;

static mapWith = "mongo"
static embedded = ["film"]

    static constraints = {
            film(validator : {Film film, def obj, def errors ->
                boolean valid = film.validate()
                if(!valid){
                    film.errors.allErrors.each {FieldError error ->
                        final String field = "film"
                        final String code = "$error.code"
                        errors.rejectValue(field,code,error.arguments,error.defaultMessage )
                    }
                }
                return valid
            }
            )
        }