I've created an edit view for my model 'Elk', but when I click submit, I only get 'null'.
In 'editElk' I prefill the form with data from the database. This data is rendering correctly in the view. The error occurs when I click 'submit'. I've commented the line giving me 'No value'. I've followed the computer-database-jpa sample, but I just cant understand why my form is returning 'no value'.
This is my controller:
import play.data.*;
import static play.data.Form.*;
@Transactional(readOnly = true)
public static Result editElk(Long id) {
Form<Elk> editElkForm = form(Elk.class).fill(Elk.findById(id));
return ok(views.html.tableio.editelk.render("Edit Elg", editElkForm));
}
@Transactional
public static Result submitEditedElk() {
Form<Elk> submittedForm = form(Elk.class).bindFromRequest();
submittedForm.get().toTableData(); // Gives: IllegalStateException: No value]
if (submittedForm.hasErrors()) {
return ok(views.html.tableio.editelk.render("Edit Elg - Error",
submittedForm));
} else {
submittedForm.get().update(submittedForm.get().getId());
return TODO;
}
}
And this is my editElk view:
@(title: String, elkForm: Form[Elk])
@import helper._
@main(title){
<h5>Edit</h5>
@form(action = routes.TableIO.submitEditedElk()) {
@inputText(elkForm("area"))
@inputText(elkForm("sex"))
@inputDate(elkForm("date"))
@inputText(elkForm("weigth"))
@inputText(elkForm("veal"))
@inputText(elkForm("antlers"))
@inputText(elkForm("age"))
@inputText(elkForm("twin"))
@inputText(elkForm("sumTick"))
@inputText(elkForm("sumLice"))
<button type="submit">Save</button>
}
}
And finally my routes file:
GET /editelk/:elkid controllers.TableIO.editElk()
POST /submitEditedElk controllers.TableIO.submitEditedElk()
Edit As requested, added the Elk class.
@Entity
public class Elk {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Required
private Date date;
@Required
private int weight;
@Required
private double age;
@Required
private int antlers;
@Required
private int veal;
@Required
private int twin;
@Required
@ManyToOne
private Tick sumTick;
@Required
@ManyToOne
private DeerLice sumLice;
@Required
@ManyToOne
private Sex sex;
@Required
@ManyToOne
private Area area;
@Required
@ManyToOne
private HuntingField huntingfield;
public static Elk findById(Long id) {
return JPA.em().find(Elk.class, id);
}
@Transactional
public void save() {
this.sumTick = Tick.findById(sumTick.id);
this.sumLice = DeerLice.findById(sumLice.id);
this.sex = Sex.findById(sex.id);
JPA.em().persist(this);
}
}
I have omitted the getters and setters.
Your first issue might be the typo you have in your weight
input field:
@inputText(elkForm("weigth")) // Should be @inputText(elkForm("weight"))
With this typo, when you submit a form there won't be a weight
key in the body of your HTTP POST request. Consequently, when you bind the POST data to a form object in the following statement:
Form<Elk> submittedForm = form(Elk.class).bindFromRequest();
The weight
attribute of the wrapped Elk
will be zero. Your form will therefore be considered invalid because weight
is a required value.
To clarify, the
IllegalStateException
you're getting isn't because there's a bug in your view or model code. It is because you're trying to unwrap a form object that contains validation errors. As the documentation and samples illustrate, you should only call theget()
method on a form after you've called.hasErrors()
and it has returnedfalse
.
After correcting this typo, I'd probably have a look at what's getting sent for your non-primitive fields (sumTick
, sumLice
, sex
, area
, huntingField
). I'm going to go ahead and assume that the associated types in your model class are enums. If this is the case, you should check that the values being submitted are names of corresponding enum values (in which case the binding will produce a valid form).
Your date
field skipped my attention. If you're submitting dates in a yyyy-MM-dd
format, add the following annotation to the date
attribute on your model class.
@Required
@Formats.DateTime(pattern="yyyy-MM-dd")
private Date date;
This is the approach taken in the sample projects. With this annotation Play will populate the Date field in your form object with the date String from the POST submission.