I am using spring and I have a child model with a objectify key object – “Key parent”
The getAsText prints ok when form is being loaded, but when the form submit, setAsText is skipped. Any reason? and the parentType is empty when it arrives the Controller. Is it the form issue or controller or the editor?
(side track: Is there an editor written for Objectify Key <-> String mapping?)
Jsp
<form:hidden path="parentType" />
Controller
@InitBinder
protected void initBinder(HttpServletRequest request,
ServletRequestDataBinder binder) throws Exception {
/** Key Conversion **/
binder.registerCustomEditor(com.googlecode.objectify.Key.class, new KeyEditor());
}
@RequestMapping(value = "/subtype-formsubmit", method = RequestMethod.POST)
public ModelAndView subTypeFormSubmit(@ModelAttribute("productSubType") @Valid ProductSubType productSubType,
BindingResult result){
ModelAndView mav = new ModelAndView();
//OK, getting the value
log.info(productSubType.getType());
//NOT OK, productSubType.getParentType() always null, and setAsText is not called?!
log.info(productSubType.getParentType().toString());
return mav;
}
KeyEditor.java
public class KeyEditor extends PropertyEditorSupport {
private static final Logger log = Logger
.getLogger(KeyEditor.class.getName());
public KeyEditor(){
super();
}
@Override
public String getAsText() {
Long id = ((Key) getValue()).getId();
String kind = ((Key) getValue()).getKind();
log.info(kind + "." + id.toString());
return kind + "." + id.toString();
}
@Override
public void setAsText(String text) throws IllegalArgumentException {
log.info(text);
String clazz = text.substring(0, text.indexOf("."));
Long id = Long.parseLong(text.substring(text.indexOf(".")));
log.info(clazz+":"+id);
Class c=null;
Key<?> key=null;
try {
c = Class.forName(clazz);
key = new Key(c, id);
} catch (Exception ex) {
log.info("ex" + ex.toString());
ex.printStackTrace();
}
setValue(key);
}
}
You need to call
Class.forNamewith the complete class name, including packages.I think that
Key#getKind()returns the simple class name without packages. Alsotext.substring(0, text.indexOf("."));(in setAsText) tells me there are no dots inclazz, so you’re not feeding the correct input toClass.forNameOptions:
clazz(not a very robust solution)ObjectifyService.register(YourEntity.class);), then you can simultaneously create a map from kind to complete class name, and then use it insetAsText.But there might be better options…