【问题标题】:Constraints on an embedded subclass - Grails, GORM, Mongo嵌入式子类的约束 - Grails、GORM、Mongo
【发布时间】:2014-11-18 12:14:34
【问题描述】:

这几天我一直在纠结这个问题。

我有一个带有几个指定约束的嵌入式子类。我的问题是这些约束永远不会强制执行, 我正在使用 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
}
}

动作电影类

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 的问题吗?是否可以在父类和子类中有约束?

保存时的示例代码

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 对象时,会按预期应用约束,但如果它是嵌入式对象,则不会应用约束。

【问题讨论】:

  • 在 ActionFilm 的约束块中尝试importFrom Film
  • @user1690588 我尝试了你的建议,但很遗憾没有奏效。

标签: mongodb grails constraints grails-orm


【解决方案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
            }
            )
        }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-18
    • 1970-01-01
    相关资源
    最近更新 更多