How to do the Hibernate validation on the nested list objects?

ashishjmeshram picture ashishjmeshram · Sep 23, 2011 · Viewed 12.2k times · Source

I need to validate the objects which are stored in the list on my form bean object.

Below is my form bean object.

public class Role implements java.io.Serializable {

    // Fields    
    private int roleId;

    @NotBlank
    private String roleName;

    private boolean active;

    @Valid
    private List<Module> modules;

    // getters anfd setters
}

and below is my object which is present in the list of my main form bean object

public class Module implements Serializable {

    private int id;

    @NotBlank
    private String moduleName;

    // other properties and getters and setters
}

Below is my properties file

# -- Role form -- 
NotBlank.role.roleName=Role Name can not be blank.
NotBlank.module.moduleName=Module Name can not be blank.

Below is My JSP page, the form consists of a role name and modules which can be added to the role.

    <table border="0" class="section_tbl2">
    <tr>
        <td width="150px" valign="top">
            <spring:message code="dmx.role.form.label.name"/>
        </td>
        <td width="10px">:</td>
        <td>
            <form:input class="txtinput" id="roleName" path="roleName" maxlength="50"/>      <form:errors path="roleName" cssClass="error"/>

        </td>
    </tr>
    <tr><td colspan="3" height="8px"></td></tr>

    <tr>
        <td width="150px" vAlign="top">
            Modules
        </td>
        <td width="10px" vAlign="top">:</td>
        <td>

            <table>
                <tr>
                    <td>
                        <input type="button" value="<spring:message code="dmx.role.form.button.addModule.label"/>" onclick="return addModuleRow();"></input>
                    </td>
                </tr>
                <tr><td>&nbsp;</td></tr>
            </table>

            <table cellpadding="0" cellspacing="0" border="0" class="tblstyle1" id="moduleTable">
                <thead>
                    <tr>
                        <th class="fst" width="200px">
                            <spring:message code="dmx.role.form.label.moduleName"/>
                        </th>
                        <th width="50px"><spring:message code="dmx.role.form.label.create"/></th>
                        <th width="50px"><spring:message code="dmx.role.form.label.update"/></th>
                        <th width="50px"><spring:message code="dmx.role.form.label.delete"/></th>
                        <th width="30px"></th>
                    </tr>
                </thead>
                <tbody id="moduleTBody">
                    <c:forEach items="${role.modules}" var="module" varStatus="status" >
                        <c:set var="moduleCounter" value="${status.index}"/>
                        <tr id="moduleRowId_${moduleCounter}">
                            <td class="fst txt-center">
                                <form:select onchange="checkIfThisModuleAlreadySelected(this);" class="seloption" id="selectedModule_${moduleCounter}" path="modules[${moduleCounter}].id">
                                    <form:option value="" label="-- Select Module --"/>
                                    <form:options items="${moduleList}" itemLabel="moduleName" itemValue="id" />
                                </form:select>
                            </td>
                            <td class="txt-center">
                                <form:checkbox id="create_${moduleCounter}" path="modules[${moduleCounter}].create"/>
                            </td>
                            <td class="txt-center">
                                <form:checkbox id="update_${moduleCounter}" path="modules[${moduleCounter}].update"/>
                            </td>
                            <td class="txt-center">
                                <form:checkbox id="delete_${moduleCounter}" path="modules[${moduleCounter}].delete"/>
                            <td class="txt-center">
                                <input class="delbtn" id="moduleDelBtn_${moduleCounter}" name="moduleDelBtn[${moduleCounter}]" type="button" onclick="delModuleRow(${moduleCounter});">
                            </td>
                        </tr>
                    </c:forEach>
                </tbody>    
            </table>                
        </td>
    </tr>
    <tr><td colspan="3" height="3px"></td></tr>
</table>

I can successfully validate the role name i.e. when role name is blank I get an error message but when module is not selected i do not get any error message.

Please help

Answer

Gunnar picture Gunnar · Sep 23, 2011

Adding @NotNull and @Size constraints to your module list should help:

@Valid
@NotNull
@Size(min = 1)
private List<Module> modules;

The @Valid annotation causes the elements of the annotated collection to be validated but it doesn't validate wether that collection is not null or contains any elements.