4

I would like to use the play.data.Form feature of Play!Framework but I am having a problem with the following classes. Could anybody tell me if there is a way to make the Forms aware of nested paths with such inheritance structures? So far what I have tried is making it work with Json. Here is a digest of my code.

@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class ContactParam implements IEntityParam<Contact> {

    private Long id;

    private String name;

    private List<ContactFieldParam> contacts;

    private Long companyId;

    //standard getters and setters
}

with the details being defined as follow:

@JsonSubTypes({
        @Type(EmailFieldParam.class),
        @Type(PhoneFieldParam.class),
        @Type(SocialNetworkFieldParam.class),
        @Type(AddressFieldParam.class),
        @Type(WebsiteUrlFieldParam.class)
})
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "ctype")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public abstract class ContactFieldParam implements IEntityParam<ContactField> {

    private Long id;

    //standard getters and setters
}

and of course all the subclasses are implemented (with quite different set of fields) and have a public default constructor available. I have tested this structure with Json (Jackson on its own AND the wrapped Json implementation in the play framework) and it works. The problem is when I try to use it in my controller by declaring a Form<ContactParam>

private static final Form<ContactParam> contactForm = Form.form(ContactParam.class);

public static Result myAction() {
     Form<ContactParam> form = contactForm.bindFromRequest();
     if(form.hasErrors){
     //...
     }else{
     //...
     }
}

The binding will give me an error caused by an InstanciationException as it is trying to directly instance the abstract class using the newInstance() method of Class<ContactFieldParam>. I determined that by studying the springframework code that is used by the Form class (DataBinder and BeanWrapperImpl).

org.springframework.beans.InvalidPropertyException: Invalid property 'contacts[0]' of bean class [crud.params.contact.ContactParam]: Illegal attempt to get property 'contacts' threw exception; nested exception is org.springframework.beans.NullValueInNestedPathException: Invalid property 'contacts' of bean class [crud.params.contact.ContactParam]: Could not instantiate property type [crud.params.contact.fields.ContactFieldParam] to auto-grow nested property path: java.lang.InstantiationException
[...]
Caused by: org.springframework.beans.NullValueInNestedPathException: Invalid property 'contacts' of bean class [crud.params.contact.ContactParam]: Could not instantiate property type [crud.params.contact.fields.ContactFieldParam] to auto-grow nested property path: java.lang.InstantiationException
    at org.springframework.beans.BeanWrapperImpl.newValue(BeanWrapperImpl.java:633)
le-doude
  • 3,345
  • 2
  • 25
  • 55

0 Answers0