我正在使用Play的CRUD模块来创建一组简单的管理屏幕。我的一个模型是用户,我想在电子邮件字段上强制执行唯一约束。
代码如下所示:
public class User extends Model {
@Email
@Required
@Column(unique=true)
public String email;
管理界面显示正确 - 当我尝试打破唯一性时(通过使用已使用过的电子邮件保存用户)我收到此错误(在浏览器中):
Execution exception
PersistenceException occured : org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
In {module:crud}/app/controllers/CRUD.java (around line 100)
96:
} catch (TemplateNotFoundException e) {
97:
render("CRUD/show.html", type, object);
98:
}
99:
}
100:
<b>object._save();</b>
101:
flash.success(Messages.get("crud.saved", type.modelName));
102:
if (params.get("_save") != null) {
103:
redirect(request.controller + ".list");
104:
}
105:
redirect(request.controller + ".show", object._key());
106:
}
我是否可以使用CRUD模块和列唯一性注释进行调整?
答案 0 :(得分:2)
您可以创建自定义检查并添加到User类中的email属性。
public class UniqueCheck extends Check { @Override public boolean isSatisfied(Object validatedObject, Object value) { if (StringUtils.isBlank((String) value)) { return false; } return User.findByEmail((String) value)); } }
然后
public class User extends Model { @Email @Required @MaxSize(value = 250) @CheckWith(value = UniqueEmail.class, message = "Existing account has been found with this e-mail") public String email; }
答案 1 :(得分:0)
在我看来,系统正在按照您的预期行事。我唯一可以想象的是修补CRUD模块以捕获此异常并且更好,但通常唯一的约束是数据库端约束,并且只能通过尝试写入数据库来检查。因此,唯一约束不是验证注释(可以在写入数据库之前执行)。