Trying to update the Address and Ninja in a One-To-One relationship in one form. I can create and validate the create objects successfully. Updating is where I am getting the errors. Specifically, when I try to populate the attribute with the current information. I get an error during validation. Works great when I don't populate the attribute with the information.
The error that I am recieving is:
Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction
Form/.jsp:
<form:form action="/ninja/update" method="PUT" modelAttribute="output">
<!-- id -->
<form:input type="hidden" path="id"/>
<form:label path="name">
Name:
</form:label>
<br>
<form:errors path="name"/>
<form:input path="name"/>
<!-- street -->
<form:input type="hidden" path="address.id"/>
<form:label path="address.street">
Street:
</form:label>
<br>
<form:errors path="address.street"/>
<form:input path="address.street"/>
<!-- city -->
<form:label path="address.city">
City:
</form:label>
<br>
<form:errors path="address.city"/>
<form:input path="address.city"/>
<!-- state -->
<form:label path="address.state">
State:
</form:label>
<br>
<form:errors path="address.state"/>
<form:input path="address.state"/>
<!-- zip -->
<form:label path="address.zip">
Zip:
</form:label>
<br>
<form:errors path="address.zip"/>
<form:input type="number" path="address.zip" min="00501"/>
<!-- dojo -->
<form:label path="dojo">
Dojo:
</form:label>
<form:select path="dojo">
<c:forEach var="d" items="${dojos}">
<form:option value="${d.id}" path="dojo">
${d.name}
</form:option>
</c:forEach>
</form:select>
<!-- submit -->
<input type="submit" value="Change Location">
</form:form>
Controller:
@Controller
public class Ninjas {
// Services
@Autowired
private AddressServ aserv;
@Autowired
private NinjaServ serv;
@Autowired
private DojoServ dserv;
// SHOW ONE and SHOW UPDATE
@GetMapping("/ninja/{id}")
public String ninjaRead( @PathVariable("id") Integer id,
Model m) {
m.addAttribute("output", serv.selectOne(id));
m.addAttribute("dojos", dserv.selectAll());
return "/ninjas/ninja.jsp";
}
// PROCESS UPDATE
@PutMapping("/ninja/update")
public String ninjaUpdate(
@Valid @ModelAttribute("output") Ninja e,
BindingResult result,
Model m) {
m.addAttribute("dojos", dserv.selectAll());
try {
aserv.save(e.getAddress());
serv.save(e);
return("redirect:/ninjas");
} catch (ConstraintViolationException ahh){
for (ConstraintViolation<?> i : ahh.getConstraintViolations()) {
result.rejectValue(String.format("address.%s", i.getPropertyPath().toString()), "error.dojo", i.getMessage());
}
return "/ninjas/ninja.jsp";
}
}
Services:
public Ninja save(Ninja e) {
return repo.save(e);
}
----
public Address save(Address e) {
return s.save(e);
}
Repositories
@Repository
public interface AddressRepo extends CrudRepository<Address, Integer>{
List<Address> findAll();
}
----
@Repository
public interface NinjaRepo extends NinjaRepository<Address, Integer>{
List<Address> findAll();
}
Models:
--- Ninja.java
// ONE TO ONE
@OneToOne(fetch=FetchType.EAGER)
@JoinColumn(name="address_id")
private Address address;
--- Address.java
// ONE TO ONE
// ninja
@OneToOne(mappedBy="address", cascade=CascadeType.ALL, fetch=FetchType.EAGER)
private Ninja ninja;
CodePudding user response:
// PROCESS UPDATE
@PutMapping("/ninja/update")
public String ninjaUpdate(
@Valid @ModelAttribute("output") Ninja e,
BindingResult result,
Model m) {
m.addAttribute("dojos", dserv.selectAll());
try {
aserv.save(e.getAddress());
serv.save(e);
return("redirect:/ninjas");
} catch (TransactionSystemException caught){
ConstraintViolationException ahh = (ConstraintViolationException) caught.getMostSpecificCause();
for (ConstraintViolation<?> i : ahh.getConstraintViolations()) {
result.rejectValue(String.format("address.%s", i.getPropertyPath().toString()), "error.dojo", i.getMessage());
}
return "/ninjas/ninja.jsp";
}
}