2011-05-30 42 views
2

如何让我的模型类字段具有唯一性?例如。如果已经登录,我想为用户显示正确的消息。我必须写我自己的验证检查并使用它,或者可以使用JPA @UniqueConstraint玩! - 独特的模型字段

回答

5

我已经这样做了:

@Entity 
public class User extends Model { 

    @Basic(optional=false) @Column(unique=true) public String name; 

    public User(String name) { 
     this.name = name; 
     create(); 
    } 

    /** used in registration to find name clash */ 
    public static User findByName(String name) { 
     return find("name", name).first(); 
    } 

} 

然后在控制器,你做这样的事情:

public static void register(@Required String name) { 
    if(User.findByName(name)!=null) { 
     Validation.addError("name", "this name is not available"); 
    } 
    if (validation.hasErrors()) { 
     validation.keep(); 
     params.flash(); 
     flash.error("Please correct the form data."); 
     signup(); // whatever your GET action was 
    } 

    User user = new User(name); 
    login(); // whatever your success action is 
} 

你可以做到这一点没有User.findByName()检查和你会得到一个ConstrainViolationException,但这当然不是非常用户友好的。您也可以尝试/捕获该异常。我更喜欢这两种方式,在数据库中用户友好且一致。

+0

我也在想抓住异常,但我觉得这有点“不整齐”。我已经做了类似于你所提议的事情,但我仍然缺少模型中的唯一性,所以我会补充说一致。 – jjczopek 2011-05-30 23:11:26

0

我通过在我的crud控制器中重写创建方法来实现此目的。在validaiton.hasErrors()方法之前调用一个自定义validateUniqueFields方法。然后,我可以为我独特的字段返回有效的错误。

public static void create() throws Exception 
{ 
    ObjectType type = ObjectType.get(getControllerClass()); 
    notFoundIfNull(type); 
    Constructor<?> constructor = type.entityClass.getDeclaredConstructor(); 
    constructor.setAccessible(true); 
    Model object = (Model) constructor.newInstance(); 
    Binder.bindBean(params.getRootParamNode(), "object", object); 
    validation.valid(object); 
    validateUniqueFields(object); 
    if (validation.hasErrors()) { 
     renderArgs.put("error", play.i18n.Messages.get("crud.hasErrors")); 
     try { 
      render(request.controller.replace(".", "/") + "/blank.html", type, object); 
     } catch (TemplateNotFoundException e) { 
      render("CRUD/blank.html", type, object); 
     } 
    } 
    object._save(); 
    flash.success(play.i18n.Messages.get("crud.created", type.modelName)); 
    if (params.get("_save") != null) { 
     redirect(request.controller + ".list"); 
    } 
    if (params.get("_saveAndAddAnother") != null) { 
     redirect(request.controller + ".blank"); 
    } 
    redirect(request.controller + ".show", object._key()); 
} 

private static void validateUniqueFields(Model object) { 
    String value = ((CastModelHere)object).identifier; 
    String ident = "identifier"; 
    if(TUCharacterTypeIdentifier.find(ident, value).first() != null) 
    { 
     validation.addError("object." + ident, ident + " already taken"); 
    } 
}