Play Framework 2.3 如何向示例应用程序添加唯一约束
Play Framework 2.3 How to add unique constraint to sample application
鉴于 Play Framework 2.3 Computer Database sample application,我想练习在属性上添加唯一约束。假设我希望 Computer
class 的 name
属性是唯一的。我试图通过向 Computer.java
:
添加一个 validate()
函数(和一个 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 中的唯一性?
谢谢!
更新:见。
我最终使用了 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:以下每个答案都是可能的解决方案
我不确定这是否回答了您的问题,因为我不熟悉 Ruby 语法。
到"create a uniqueness constraint in the database"可以使用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;
...
}
希望对您有所帮助!
您需要从唯一检查中排除当前实体,即像这样:
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
P.S. ne()
表达式代表 不等于 当然,这种方法假定您name
字段是 Required
编辑: 我向您发送了带有工作解决方案的拉取请求,您只需在 editForm
中添加隐藏字段,例如:
<input name="id" type="hidden" value='@computerForm("id").value'/>
另一件事是您可以简化模型,即不需要 public 字段的吸气剂。
鉴于 Play Framework 2.3 Computer Database sample application,我想练习在属性上添加唯一约束。假设我希望 Computer
class 的 name
属性是唯一的。我试图通过向 Computer.java
:
validate()
函数(和一个 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 中的唯一性?
谢谢!
更新:见
我最终使用了 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:以下每个答案都是可能的解决方案
我不确定这是否回答了您的问题,因为我不熟悉 Ruby 语法。
到"create a uniqueness constraint in the database"可以使用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;
...
}
希望对您有所帮助!
您需要从唯一检查中排除当前实体,即像这样:
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
P.S. ne()
表达式代表 不等于 当然,这种方法假定您name
字段是 Required
编辑: 我向您发送了带有工作解决方案的拉取请求,您只需在 editForm
中添加隐藏字段,例如:
<input name="id" type="hidden" value='@computerForm("id").value'/>
另一件事是您可以简化模型,即不需要 public 字段的吸气剂。