Announcement Announcement Module
No announcement yet.
Using SimpleFormController when domain object is subclassed Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Using SimpleFormController when domain object is subclassed


    I have two domain objects:
    - Person
    - User, which extends Person

    I have an HTML form where the basic properties of a person (which includes a user) can be changed. This form is controlled by a SimpleFormController whose "commandClass" property is set to Person.class.

    My onSubmit() method calls PersonService.update(Person), which sets some fields (last updated on, last updated by), then calls PersonDAO.update(Person). My DAO is implemented using Hibernate, and in case it's relevant, my Hibernate mapping file uses the "class hierarchy per table" approach, i.e. the "person" db table contains both Person and User objects.

    The Problem

    This all works fine when the person being edited is an instance of Person. However if the person is a User, the DAO throws an exception with the message "Object with id: null was not of the specified subclass: Person (class of the given object did not match class of persistent copy)".

    Some logging in the controller tells me that the command object passed to onSubmit(), and which I am passing on to the PersonService, is an instance of Person (not surprising, given that I configured the controller's command class to be Person.class). FWIW, at this point the Hibernate session contains a CGLIB-generated "User" proxy with the same ID as the user being edited. I'm using the OpenSessionInViewInterceptor if that makes any difference.

    My Questions

    I'd like to know if there's a way to set up a SimpleFormController to handle this kind of class structure, i.e. so that it uses a command object that is of the same class as the object being edited, e.g. the command would be a Person object when a person was being edited, and a User object when a user was being edited. Or is this asking too much of SimpleFormController?

    How do other people handle this scenario?

  • #2
    You can override the formBackingObject() method can control the exact object instance that is used as the form object. The default implementation provided by Spring will simply create an instance of the configured commandClass.



    • #3
      Problem Solved!

      Thanks Rob, you helped me get the last 5%. I had this:
      protected Object formBackingObject(HttpServletRequest req) throws Exception
        if (isFormSubmission(req)) {
          // Do what the superclass would do
          return super.formBackingObject(req);
        else {
          // Do the right thing, i.e. get a defaulted Person for an "add" action
          // or get the existing Person from the PersonService for an "edit" action
      When I removed the "if" test, it worked. This also solved my quandary about losing the values of non-editable fields that weren't in the form.

      Many thanks, and great framework.