I’m lost for ideas as to why this controller method is not working, but maybe someone has seen something like this before. My web form supplies all the Property object’s variables (one of them being the id) using the masqueraded PUT method. It’s annotated like this:
package uk.co.nicshouse.jester.domain;
import java.io.Serializable;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Property implements Serializable
{
@Id
@GeneratedValue
private long id;
private String name;
private String description;
@Embedded
private Address address;
@Override
public boolean equals(Object obj)
{
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Property other = (Property) obj;
if (this.id != other.id) {
return false;
}
if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
return false;
}
if ((this.description == null) ? (other.description != null) : !this.description.equals(other.description)) {
return false;
}
if (this.address != other.address && (this.address == null || !this.address.equals(other.address))) {
return false;
}
return true;
}
@Override
public int hashCode()
{
int hash = 3;
hash = 29 * hash + (int)this.id;
hash = 29 * hash + (this.name != null ? this.name.hashCode() : 0);
hash = 29 * hash + (this.description != null ? this.description.hashCode() : 0);
hash = 29 * hash + (this.address != null ? this.address.hashCode() : 0);
return hash;
}
@Override
public String toString()
{
return "Property{" + "id=" + id + ", name=" + name + ", description=" + description + ", address=" + address + '}';
}
public long getId()
{
return id;
}
public void setId(long id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getDescription()
{
return description;
}
public void setDescription(String description)
{
this.description = description;
}
public Address getAddress()
{
return address;
}
public void setAddress(Address address)
{
this.address = address;
}
}
The controller looks like this:
package uk.co.nicshouse.jester.mvc;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.portlet.ModelAndView;
import uk.co.nicshouse.jester.domain.Property;
import uk.co.nicshouse.jester.service.PropertyService;
@Controller
@RequestMapping("/property")
public class PropertyController
{
@Autowired
private PropertyService propertyService;
/*
* Methods that return views
*/
@RequestMapping(method=RequestMethod.GET, produces="text/html")
public String listProperty(Model model, HttpServletRequest request)
{
model.addAttribute( propertyService.getAll() );
model.addAttribute("hostname", request.getServerName());
return "property/list";
}
@RequestMapping(value="/{id}", method=RequestMethod.GET, produces="text/html")
public String viewProperty(@PathVariable long id, Model model)
{
model.addAttribute( propertyService.getById(id) );
return "property/view";
}
@RequestMapping(value="/{id}/edit", method=RequestMethod.GET, produces="text/html")
public String editProperty(@PathVariable long id, Model model)
{
model.addAttribute( propertyService.getById(id) );
return "property/edit";
}
@RequestMapping(value="/new", method=RequestMethod.GET, produces="text/html")
public String newProperty(Model model)
{
model.addAttribute( new Property() );
return "property/edit";
}
@RequestMapping(value="/new", method=RequestMethod.POST)
public String createProperty(@Valid Property property, BindingResult bindingResult)
{
getPropertyService().create(property);
return "redirect:/property/" + property.getId();
}
@RequestMapping(value="/**", method=RequestMethod.PUT)
public String updateProperty(@RequestParam("id") int id, Property property)
{
System.out.println("Supplied id: " + id);
System.out.println("Supplied property: " + property);
getPropertyService().update(property);
return "redirect:/property/" + property.getId();
}
public PropertyService getPropertyService()
{
return propertyService;
}
public void setPropertyService(PropertyService propertyService)
{
this.propertyService = propertyService;
}
}
And the form as generated by jstl looks like this:
<form id="property" action="/jester/property/1/edit" method="post" enctype="multipart/form-data"><input type="hidden" name="_method" value="PUT"/>
<input id="id" name="id" type="hidden" value="3"/>
<div>
<label for="name">Name</label>
<input id="name" name="name" type="text" value="Test Name" size="15"/><br/>
</div>
<div>
<label for="description">Description</label>
<textarea id="description" name="description" size="15">Test Description Here</textarea><br/>
</div>
<div>
<label for="address.street">Street</label>
<input id="address.street" name="address.street" type="text" value="Test Street" size="15"/><br/>
</div>
<div>
<label for="address.borough">Borough</label>
<input id="address.borough" name="address.borough" type="text" value="" size="15"/><br/>
</div>
<div>
<label for="address.town">Town</label>
<input id="address.town" name="address.town" type="text" value="Test Town" size="15"/><br/>
</div>
<div>
<label for="address.county">County</label>
<input id="address.county" name="address.county" type="text" value="Test County" size="15"/><br/>
</div>
<div>
<label for="address.postcode">Postcode</label>
<input id="address.postcode" name="address.postcode" type="text" value="TT11 1TT" size="15"/><br/>
</div>
<div>
<label for="address.country">Country</label>
<input id="address.country" name="address.country" type="text" value="UK" size="15"/><br/>
</div>
<div>
<input type="submit" value="Save" />
<input type="reset" />
</div>
The strange thing is that the id==3 (the correct value from the HTML form), but property.id==0! Property’s other variables are set correctly. Any ideas why this is happening?
Figured this one out, it was a bug on my part. Property.id’s type was long but Property.setId accepted an int. This seems to have screwed Spring up in some way! Thanks for your efforts though! NFV