I have an Entity Campaign that has a OneToOne relationship with CampaignCities cities. In turn, CampaignCities contains a Set cities;
The campaign entity
@Entity
@javax.persistence.Table(uniqueConstraints={@UniqueConstraint(columnNames={"name","company_id"}), @UniqueConstraint(columnNames={"id"})})
public class Campaign implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private Long id;
@NotEmpty
@Size(min=1, max=100)
private String name;
private Date startDate;
private Date endDate;
@Valid
private Deal deal;
@Valid
private Company company;
@OneToOne
private CampaignCities cities = new CampaignCities();
The CampaignCities entity
@Entity
public class CampaignCities {
private long id;
private Set<City> cities = new HashSet<City>();
@Id
@javax.persistence.GeneratedValue(strategy=GenerationType.AUTO)
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
@OneToMany
public Set<City> getCities() {
return cities;
}
public void setCities(Set<City> cities) {
this.cities = cities;
}
}
The City entity:
@Entity
public class City implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private String name;
private Long id;
@javax.persistence.Id
@javax.persistence.GeneratedValue(strategy=GenerationType.AUTO)
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;
}
}
My NewCampaignController
@SessionAttributes(value={"campaign", "campaignCities"})
@Controller
public class NewCampaignController {
//private static final Logger logger = LoggerFactory.getLogger(NewDealController.class);
@Autowired
private CampaignManager campaignManager;
@Autowired
private CityManager cityManager;
@Autowired
SimpleDateFormat dateFormat;
@Autowired
CustomDateEditor dateEditor;
@RequestMapping(value = "campaign/new", method = RequestMethod.GET)
public String showForm(Map<String, Object> model) {
//List<Campaign> campaigns = campaignManager.getCampaigns();
Campaign campaignForm = new Campaign();
CampaignCities cities = new CampaignCities();
cities.setCities(new HashSet<City>(cityManager.getCity()));
//campaignForm.setCities(cities);
model.put("campaignCities", cities);
model.put("campaign", campaignForm);
return "campaign/new";
}
@RequestMapping(value = "campaign/new", method = RequestMethod.POST)
public String processForm(@Valid Campaign campaignForm, BindingResult result, Map<String,Object> model) {
new CampaignValidator().validate(campaignForm, result);
if (result.hasErrors()) {
return "campaign/new";
}
this.campaignManager.saveCampaign(campaignForm);
model.put("campaign", campaignForm);
model.put("campaigns", this.campaignManager.getCampaigns());
return "campaign/added";
}
I have been able to get campaign to render in a form and I've rendered the list of cities successfully using:
<form:checkboxes items="${campaignCities.cities}" path="cities" itemLabel="name" itemValue="id" delimiter="<br/>" />
However when i submit the form, I get the following validation error.
Field error in object 'campaign' on field 'cities': rejected value [2,1]; codes [typeMismatch.campaign.cities,typeMismatch.cities,typeMismatch.com.groupdealclone.app.domain.CampaignCities,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [campaign.cities,cities]; arguments []; default message [cities]]; default message [Failed to convert property value of type 'java.lang.String[]' to required 开发者_Python百科type 'com.groupdealclone.app.domain.CampaignCities' for property 'cities'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String[]] to required type [com.groupdealclone.app.domain.CampaignCities] for property 'cities': no matching editors or conversion strategy found]
I've tried to figure out a way to handle this in SpringMVC 3 but I've been stuck for over a day with no success. I simply want a List or Set or Cities that where checked on the form to be submitted to the controller and added to the Campaign. How do I get around the conversion problem where I can convert the String[] returned to a List or Set of Cities.
The project I'm working on is a public GitHub project, you can download the source and set it up using Maven if you like the project is called Group-Deal-Clone
After what is almost 2 days, the answer was simpler than I expected. Thanks to this thread I was guided to the answer.
In my NewCampaignController I did:
@InitBinder
public void initBinder(WebDataBinder binder) {
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, dateEditor);
binder.registerCustomEditor(CampaignCities.class, "cities", new PropertyEditorSupport() {
@Override
public void setAsText(String text) {
String [] ids = text.split(",");
CampaignCities cities = null;
for(String id:ids){
if(cities == null)
cities = new CampaignCities();
City city = cityManager.getCity(new Long(id));
if(city != null)
cities.getCities().add(city);
}
if(cities != null){
cities.setId(null);
setValue(cities);
}
}
});
精彩评论