Given the Play Framework 2.3 Computer Database sample application, I would like to practice adding a unique constraint on an attribute. Let's say I want the name
attribute of the Computer
class to be unique. I've tried to do this by adding a validate()
function (and a getter) to Computer.java
:
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;
}
This check works when creating new records in the database, however, this now causes a validation error when you update a Computer object but don't change the name. Is there a way to add a uniqueness constraint, similar to Rails? How can I validate uniqueness in Play?
Thanks!
UPDATE: see the answer by davide.
I ended up using the @Column(unique = true)
constraint from the javax.persistence API. This doesn't generate an error in Play forms; instead, it throws a PersistenceException
. Therefore I had to add change my controller to achieve the behavior I wanted. Both the create()
and update()
actions need a try/catch like this:
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));
}
UPDATE 2: each of the answers below is a possible solution
I not sure if this answer your question, because I'm not familiar with Ruby syntax.
To "create a uniqueness constraint in the database" you can use the javax persistence API. Ebean will also recognize this.
To have a plain uniqueness constraint which involves a single field, you can use the
@Column
annotation:If you need some combination of fields to be unique, instead use the
@Table
annotationI hope it helps!
You need to exclude current entity from unique checking, i.e. like that:
It will give you SQL query during update:
And this during create:
P.S.
ne()
expression stands for Not Equal To and of course this approach assumes that yourname
field isRequired
Edit: I sent you pull request with working solution, all you need is to add hidden field in your
editForm
like:Other thing is that you can simplify your model, i.e. don't need for getters for public fields.