I have a project based on the Spring Web model-view-controller (MVC) framework. The version of the Spring Web-model-view-controller (MVC) structure is 3.2.8.
This class
public class DeviceForm { Device device; List<String> selectedItems = Collections.emptyList(); public DeviceForm() { super(); } public Device getDevice() { return device; } public void setDevice(Device device) { this.device = device; } public List<String> getSelectedItems() { return selectedItems; } public void setSelectedItems(List<String> selectedItems) { this.selectedItems = selectedItems; } }
and this one
public class Device implements java.io.Serializable { @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "CRITERIA") private BaseCriteria criteria; public BaseCriteria getCriteria() { return criteria; } public void setCriteria(BaseCriteria criteria) { this.criteria = criteria; } }
and this one
@Entity @Table(name = "CRITERIA") @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name = "DISCRIMINATOR", discriminatorType = DiscriminatorType.STRING) @SequenceGenerator(name = "seqCriteria", sequenceName = "SEQ_CRITERIA", allocationSize = 1) public abstract class BaseCriteria { public BaseCriteria() { super(); } private Long id; private String code; private Date adoptionDate; private Date expirationDate; @Transient public abstract String getGroupKey(); @Transient public abstract Long getGroupId(); @Transient public abstract String getRefColumnName(); @Id @Column(name = "ID", unique = true, nullable = true) @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seqCriteria") public Long getId() { return id; } public void setId(Long id) { this.id = id; } @Column(name = "CODE") public String getCode() { return code; } public void setCode(String code) { this.code = code; } @Column(name = "ADOPTION_DATE") @Temporal(TemporalType.TIMESTAMP) public Date getAdoptionDate() { return adoptionDate; } public void setAdoptionDate(Date adoptionDate) { this.adoptionDate = adoptionDate; } @Column(name = "EXPIRATION_DATE") @Temporal(TemporalType.TIMESTAMP) public Date getExpirationDate() { return expirationDate; } @Transient public boolean isExpired() { return getExpirationDate().before(new Date()); } public void setExpirationDate(Date expirationDate) { this.expirationDate = expirationDate; } @Override public String toString() { return "BaseCriteria [id=" + id + ", code=" + code + ", adoptionDate=" + adoptionDate + ", expirationDate=" + expirationDate + "]"; } }
and jsp
<form:form commandName="deviceForm" name="deviceForm" id="deviceFormId" method="post" action="${contextPath}/newdesign/manage/device/${deviceForm.device.id}" htmlEscape="yes"> <div class="col-sm-6 text-right"> <button class="btn btn-primary" type="submit">Save device</button> </div> </div> <c:forEach items="${deviceForm.device.productGroup.criteria}" var="criteria"> <div class="row"> <div class="col-md-3"> <form:radiobutton path="device.criteria.id" value="${criteria.id}"/> <label for="basic-url">Criteria:</label> <input value="${criteria.code}" disabled="disabled" class="form-control"/> </div> <div class="col-md-3"> <label for="basic-url">Adoption date:</label> <input value="<fmt:formatDate type="date" value="${criteria.adoptionDate}" />" disabled="disabled" class="form-control"/> </div> <div class="col-md-3"> <label for="basic-url">Expiration Date:</label> <input value="<fmt:formatDate type="date" value="${criteria.expirationDate}" />" disabled="disabled" class="form-control"/> </div> </div> </c:forEach> </form:form>
Controller:
@RequestMapping(value = { "/newdesign/manage/device/{appId}", "/newdesign/manage/device/{appId}/"}, method = {RequestMethod.GET}) public String viewDevicesWithStatus( @ModelAttribute("deviceForm") DeviceForm deviceForm, @PathVariable Long appId, HttpServletRequest request, Model model ) throws Exception { Device device = manageLicenseService.getDeviceById(appId, true); if (device.getCriteria()==null) { device.setCriteria(device.getProductGroup().getCriteria().get(0)); } deviceForm.setDevice(device); fillModel (model, request, device); return "cbViewDeviceInfo"; } @RequestMapping(value = { "/newdesign/manage/device/{appId}", "/newdesign/manage/device/{appId}/"}, method = {RequestMethod.POST}) public String saveDevicesWithStatus( @ModelAttribute("deviceForm") DeviceForm deviceForm, @PathVariable Long appId, HttpServletRequest request, Model model ) throws Exception { Device device = manageLicenseService.getDeviceById(deviceForm.getDevice().getId()); if (device.getCriteria()==null) { device.setCriteria(device.getProductGroup().getCriteria().get(0)); }
But I got the following error, when I submitted the form, using the GET method I got the same page without errors
org.springframework.beans.NullValueInNestedPathException: Invalid property 'device.criteria' of bean class [com.tdk.iot.controller.newdesign.manage.DeviceForm]: Could not instantiate property type [com.tdk.iot.domain.criteria.BaseCriteria] to auto-grow nested property path: java.lang.InstantiationException