Announcement Announcement Module
Collapse
No announcement yet.
Type erasure of command object using generics in Spring MVC Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Type erasure of command object using generics in Spring MVC

    I have also asked that question in StackOverflow but i didn't get an answer.

    I would appreciate very much any feedback please.

    In a Spring 3.1 MVC app with Hibernate 4.1, the scenario is:
    • a webpage displays a list of records where the user is able to select records with a checkbox
    • on POST, the selected records will be deleted

    Since this functionality also appears in other places, i would like to use generics in order to avoid replicating the similar code.

    The logic is:
    • on GET, i populate a list using generics which holds the hibernate object and a boolean and i am adding that list to the model
    • on POST, i obtain that list from the model and i am passing it to a service in order to delete the selected records

    The code is:

    Code:
    /* list item */
    public class SelectionListItem<T> {
    
        /* holds the hibernate object */
        private T item;
        /* whether the record is selected */
        private boolean selected;
    
        public SelectionListItem() {
    
        }
    
        public SelectionListItem(T item, boolean selected) {
            this.item = item;
            this.selected = selected;
        }
    
        public T getItem() {
            return item;
        }
    
        public void setItem(T item) {
            this.item = item;
        }
    
        public boolean isSelected() {
            return selected;
        }
    
        public void setSelected(boolean selected) {
            this.selected = selected;
        }
    }
    
    /* list that holds the records */
    public class SelectionList<T> {
    
        private List<SelectionListItem<T>> list = new ArrayList<SelectionListItem<T>>();
    
        public SelectionList() {
    
        }
    
        public List<SelectionListItem<T>> getList() {
            return list;
        }
    
        public void setList(List<SelectionListItem<T>> list) {
            this.list = list;
        }
    }
    
    
    /* Controller for GET */
    @RequestMapping(value = "/xxx", method = RequestMethod.GET)
    public String functionGET(Model model) {
        // Retrieve data from database and prepare the list
        SelectionList<MyDomainObject> selectionList = someService.getRecordsAndPrepareList();
    
        // Add command object to model
        model.addAttribute("selectionListCommand", selectionList);
    
    
        return "xxx";
    }
    
    /* Service that retrieves the records and prepares the list */
    public SelectionList<MyDomainObject> getRecordsAndPrepareList() {
        List<MyDomainObject> result = sessionFactory.getCurrentSession().createCriteria(MyDomainObject.class).list();
    
        SelectionList<MyDomainObject> selectionList = new SelectionList<MyDomainObject>();
        for (MyDomainObject item : result) {
            SelectionListItem<MyDomainObject> e = new SelectionListItem<MyDomainObject>(item, false);
            selectionList.getList().add(e);
        }
    
        return selectionList;
    }
    
    /* Controller for POST */
    @RequestMapping(value = "/xxx", method = RequestMethod.POST)
    public String functionPOST(
        @ModelAttribute("selectionListCommand") SelectionList<MyDomainObject> selectionListCommand,
        BindingResult result, Model model) {
    
        // Delete record
        someService.deleteSelectedRecords(selectionListCommand);
    
    
        return "xxx;
    }
    
    /* Service that deletes the selected records*/
    public void deleteSelectedRecords(SelectionList<MyDomainObject> selectionList) {
        for (SelectionListItem<MyDomainObject> item : selectionList.getList()) {
            if (item.isSelected()) {
                sessionFactory.getCurrentSession().delete(item.getItem());
            }
        }
    }
    At GET request, the SelectionList is populated correctly and the "T item" is of type "MyDomainObject".

    At POST, the "T item" is of type "java.lang.Object" and when the "sessionFactory.getCurrentSession().delete(item.ge tItem())" is executed i am getting "org.hibernate.MappingException: Unknown entity: java.lang.Object"

    Can someone please explain what is causing it and how it can be solved?

    Thank you in advance.

  • #2
    As i mentioned, the problem was when the @ModelAttribute("selectionListCommand") was returned at POST.

    Solution is:
    • Add to the controller -> @SessionAttributes("selectionListCommand")
    • Modify class SelectionList to -> public class SelectionList<T> implements java.io.Serializable

    I hope that will save someone's else time in the future.

    Comment

    Working...
    X