2011-05-30 89 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"); 
    } 
}