Home > Software design >  Update two tables in one form. Spring, Java
Update two tables in one form. Spring, Java

Time:05-06

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";
      }
}
  • Related