鉴于Play Framework 2.3 Computer Database sample application,我想练习在属性上添加唯一约束。假设我希望name
类的Computer
属性是唯一的。我试图通过向validate()
添加Computer.java
函数(和getter)来实现此目的:
public List<ValidationError> validate() {
List<ValidationError> errors = new ArrayList<ValidationError>();
if(Computer.find.where().eq("name", getName()).findRowCount() != 0){
errors.add(new ValidationError("name", "Name must be unique. That value is already taken."));
}
return errors;
}
public String getName() {
return name;
}
此检查在数据库中创建新记录时有效,但是,当您更新计算机对象但不更改名称时,现在会导致验证错误。有没有办法添加uniqueness constraint, similar to Rails?如何在Play中验证唯一性?
谢谢!
更新:请参阅answer by davide。
我最终使用了javax.persistence API中的@Column(unique = true)
约束。这不会在Play表单中生成错误;相反,它会抛出一个PersistenceException
。因此我不得不添加更改我的控制器以实现我想要的行为。 create()
和update()
操作都需要像这样的try / catch:
try {
computerForm.get().save();
} catch (PersistenceException pe) {
flash("error", "Please correct errors below.");
formData.reject("name", "Name conflict. Please choose a different name.");
return badRequest(createForm.render(computerForm));
}
更新2 :以下每个答案都是可能的解决方案
答案 0 :(得分:2)
我不确定这是否能回答你的问题,因为我不熟悉Ruby语法。
要“在数据库中创建唯一性约束”,您可以使用javax persistence API。 Ebean也会认识到这一点。
要拥有涉及单个字段的普通唯一性约束,您可以使用@Column
annotation:
@Entity
public class Computer extends Model {
...
@Column(unique = true)
public String name;
...
}
如果您需要某些字段组合是唯一的,请使用
@Table
annotation
@Table(
uniqueConstraints=
@UniqueConstraint(columnNames={"name", "brand"})
)
@Entity
public class Computer extends Model {
...
public String name;
public String brand;
...
}
我希望它有所帮助!
答案 1 :(得分:2)
您需要从唯一检查中排除当前实体,例如:
if(Computer.find.where().eq("name", getName()).ne("id", getId()).findRowCount() != 0){
errors.add(new ValidationError("name", "Name must be unique."));
}
它将在更新期间为您提供SQL查询:
select count(*) from computer t0 where t0.name = 'Foo' and t0.id <> 123
这在创作期间:
select count(*) from computer t0 where t0.name = 'Foo' and t0.id is not null
PS ne()
表达式代表 Not Equal To ,当然这种方法假定您的name
字段为Required
< / p>
修改:我向您发送了带有工作解决方案的拉取请求,您只需在editForm
中添加隐藏字段,如:
<input name="id" type="hidden" value='@computerForm("id").value'/>
其他方面是您可以简化模型,即不需要公共字段的getter。