4

I have developed a web application using Spring 3.1

In one of the module I need to save one Operation object having many OperationParameter objects. So in the view I have provided add button for user to create OperationParameters for the particular Operation.

Both the models have hibernate mapping and there is one to many relation between Operation and OperationParameter. And in Operation model I have List of OperationParameters that will be inserted in database when a new Operation will be created with dynamically added OperationParameters by the user.

When I don't use validation it works fine. When I do insert operation for Operation model the list of OperationParameters will also be inserted in the OperationParameter table.

My question is that how can I do server side validation for OperationParameter fields? And if validation is done with errors then how can I show the error of particular OperationParameter field?

Operation.java

    package com.abcprocure.servicerepo.model;
// Generated Feb 9, 2012 11:30:06 AM by Hibernate Tools 3.2.1.GA


import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import org.apache.commons.collections.FactoryUtils;
import org.apache.commons.collections.list.LazyList;

@Entity
@Table(name="Operations"
    ,schema="dbo"

)
public class Operations  implements java.io.Serializable {


     private int operationId;
     @Embedded
     private Services services;
     private String operationName;
     private String isHqlsql;
     private String isMultipleTables;
     private String listOfTablesAffected;
     private String hqlQuery;
     private String typeOfOperation;
     private String operationDetail;
     private String inputVariables;
     private String outputparamdatatype;
     private String isCountQuery;
     private String isDynamicWhereQry;
     private String isPaginationRequired;
     private String biInputParameters;
    private List<OperationParameters> operationParameterses = LazyList
            .decorate(new ArrayList<OperationParameters>(),
                    FactoryUtils.instantiateFactory(OperationParameters.class));

    public Operations() {
    }


    public Operations(int operationId, Services services, String operationName) {
        this.operationId = operationId;
        this.services = services;
        this.operationName = operationName;
    }
    public Operations(int operationId, Services services, String operationName, String isHqlsql, String isMultipleTables, String listOfTablesAffected, String hqlQuery, String typeOfOperation, String operationDetail, String inputVariables, String outputparamdatatype, String isCountQuery, List operationParameterses) {
       this.operationId = operationId;
       this.services = services;
       this.operationName = operationName;
       this.isHqlsql = isHqlsql;
       this.isMultipleTables = isMultipleTables;
       this.listOfTablesAffected = listOfTablesAffected;
       this.hqlQuery = hqlQuery;
       this.typeOfOperation = typeOfOperation;
       this.operationDetail = operationDetail;
       this.inputVariables = inputVariables;
       this.outputparamdatatype = outputparamdatatype;
       this.isCountQuery = isCountQuery;
       this.operationParameterses = operationParameterses;
    }

    @Id 
    @GeneratedValue
    @Column(name="operationId", unique=true, nullable=false)
    public int getOperationId() {
        return this.operationId;
    }

    public void setOperationId(int operationId) {
        this.operationId = operationId;
    }

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="serviceId", nullable=false)
    public Services getServices() {
        return this.services;
    }

    public void setServices(Services services) {
        this.services = services;
    }

    @Column(name="operationName", nullable=false, length=250)
    public String getOperationName() {
        return this.operationName;
    }

    public void setOperationName(String operationName) {
        this.operationName = operationName;
    }

    @Column(name="isHQLSQL", length=50)
    public String getIsHqlsql() {
        return this.isHqlsql;
    }

    public void setIsHqlsql(String isHqlsql) {
        this.isHqlsql = isHqlsql;
    }

    @Column(name="isMultipleTables", length=50)
    public String getIsMultipleTables() {
        return this.isMultipleTables;
    }

    public void setIsMultipleTables(String isMultipleTables) {
        this.isMultipleTables = isMultipleTables;
    }

    @Column(name="listOfTablesAffected", length=500)
    public String getListOfTablesAffected() {
        return this.listOfTablesAffected;
    }

    public void setListOfTablesAffected(String listOfTablesAffected) {
        this.listOfTablesAffected = listOfTablesAffected;
    }

    @Column(name="hqlQuery")
    public String getHqlQuery() {
        return this.hqlQuery;
    }

    public void setHqlQuery(String hqlQuery) {
        this.hqlQuery = hqlQuery;
    }

    @Column(name="typeOfOperation", length=50)
    public String getTypeOfOperation() {
        return this.typeOfOperation;
    }

    public void setTypeOfOperation(String typeOfOperation) {
        this.typeOfOperation = typeOfOperation;
    }

    @Column(name="operationDetail")
    public String getOperationDetail() {
        return this.operationDetail;
    }

    public void setOperationDetail(String operationDetail) {
        this.operationDetail = operationDetail;
    }

    @Column(name="inputVariables", length=5000)
    public String getInputVariables() {
        return this.inputVariables;
    }

    public void setInputVariables(String inputVariables) {
        this.inputVariables = inputVariables;
    }

    @Column(name="outputparamdatatype", length=50)
    public String getOutputparamdatatype() {
        return this.outputparamdatatype;
    }

    public void setOutputparamdatatype(String outputparamdatatype) {
        this.outputparamdatatype = outputparamdatatype;
    }

    @Column(name="isCountQuery", length=10)
    public String getIsCountQuery() {
        return this.isCountQuery;
    }

    public void setIsCountQuery(String isCountQuery) {
        this.isCountQuery = isCountQuery;
    }

    public String getIsDynamicWhereQry() {
        return isDynamicWhereQry;
    }


    public void setIsDynamicWhereQry(String isDynamicWhereQry) {
        this.isDynamicWhereQry = isDynamicWhereQry;
    }


    public String getIsPaginationRequired() {
        return isPaginationRequired;
    }


    public void setIsPaginationRequired(String isPaginationRequired) {
        this.isPaginationRequired = isPaginationRequired;
    }

    public String getBiInputParameters() {
        return biInputParameters;
    }


    public void setBiInputParameters(String biInputParameters) {
        this.biInputParameters = biInputParameters;
    }

    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="operations")
    public List<OperationParameters> getOperationParameterses() {
        return this.operationParameterses;
    }

    public void setOperationParameterses(List<OperationParameters> operationParameterses) {
        this.operationParameterses = operationParameterses;
    }

}

OperationParameters.java

package com.abcprocure.servicerepo.model;

// Generated Feb 9, 2012 11:30:06 AM by Hibernate Tools 3.2.1.GA


import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name="OperationParameters"
    ,schema="dbo"

)
public class OperationParameters  implements java.io.Serializable {


     private int parameterId;
     private Operations operations;
     private String inputOutputParamName;
     private String inputOutputParamType;
     private String inputOutputParamDataType;

    public OperationParameters() {
    }

    public OperationParameters(int parameterId, Operations operations, String inputOutputParamName, String inputOutputParamType, String inputOutputParamDataType) {
       this.parameterId = parameterId;
       this.operations = operations;
       this.inputOutputParamName = inputOutputParamName;
       this.inputOutputParamType = inputOutputParamType;
       this.inputOutputParamDataType = inputOutputParamDataType;
    }

    @Id 
    @GeneratedValue
    @Column(name="parameterId", unique=true, nullable=false)
    public int getParameterId() {
        return this.parameterId;
    }

    public void setParameterId(int parameterId) {
        this.parameterId = parameterId;
    }
@ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="operationId", nullable=false)
    public Operations getOperations() {
        return this.operations;
    }

    public void setOperations(Operations operations) {
        this.operations = operations;
    }

    @Column(name="inputOutputParamName", nullable=false, length=250)
    public String getInputOutputParamName() {
        return this.inputOutputParamName;
    }

    public void setInputOutputParamName(String inputOutputParamName) {
        this.inputOutputParamName = inputOutputParamName;
    }

    @Column(name="inputOutputParamType", nullable=false, length=250)
    public String getInputOutputParamType() {
        return this.inputOutputParamType;
    }

    public void setInputOutputParamType(String inputOutputParamType) {
        this.inputOutputParamType = inputOutputParamType;
    }

    @Column(name="inputOutputParamDataType", nullable=false, length=250)
    public String getInputOutputParamDataType() {
        return this.inputOutputParamDataType;
    }

    public void setInputOutputParamDataType(String inputOutputParamDataType) {
        this.inputOutputParamDataType = inputOutputParamDataType;
    }




}

Conroller method to serve the post request to add new Operation.

/**
     * Method that will serve the post request to add the operation and operation parameters submitted by the user.
     * @param operations
     * @param map
     * @return {@link String} The view name that will redirect to the get request to display the previous page with newly entered operation in the list. 
     */
    @RequestMapping(value="/add", method=RequestMethod.POST)
    public String addOperations(@ModelAttribute Operations operations, ModelMap map) {
        operations.getOperationParameterses().removeAll(Collections.singleton(null));

        for(int i=0; i<operations.getOperationParameterses().size(); i++) {
            System.out.println("parameterName :: " + ((OperationParameters)operations.getOperationParameterses().get(i)).getInputOutputParamName());
            if(((OperationParameters)operations.getOperationParameterses().get(i)).getInputOutputParamName() == null || "".equalsIgnoreCase((((OperationParameters)operations.getOperationParameterses().get(i))).getInputOutputParamName())) {
                operations.getOperationParameterses().remove(i);
                System.out.println("empty parameter removed....");
            }
        }

        return "redirect:/operations/" + operations.getServices().getServiceId();
    }

Any good suggestion or example in this regard will be a great help to me. :)

**

Update

**

I would also like to know whether it is possible to validate an array of fields and show the error back in the jsp file?

Please help me out.

Japan Trivedi
  • 4,445
  • 2
  • 23
  • 44

2 Answers2

5

You could create a helper class that validates your OperationParameters based on its data type. In case of strings, check for null or empty strings and so on. The verification class, could also have some context verification like valid e-mail address.

Having this in hands, before saving a Operations object, you would iterate through Operations list of OperationParameters, checking the data type and/or a field holding the context of the information(e.g. e-mail, weekdays) and calling the the proper validation on your helper class.

If you do catch an inconsistency, just throw a custom exception describing it. The part of your code that treats it can return a json to your page with the offending field, which in turn will give the feedback to the user (i.e. a red text under the field with your error message).

Tolio
  • 1,023
  • 13
  • 30
  • Thanks for your response. You are very close to what I wanted but not the exact thing. As per your answer I need to validate the dynamically generated fields with help of ajax. But I don't want to do that. I want to validate it when user submits the form back to the controller(Like we do in general). But the exact solution is described by me just when you post this answer(what a co-insident!!). Please check my answer. Still +1 for you efforts. :) – Japan Trivedi May 21 '12 at 12:56
  • Why did you think I was talking about ajax? I meant that you would create a class with methods to validate your data(the helper class), then use it inside your methods addOperations for loop. All server side. If you catch an error, you can do a redirect to an error page OR return some json describing the error(the ajax way). – Tolio May 21 '12 at 13:08
  • Okies then. I am accepting your answer. You have given the similar answer as I have done. Anyways thanks for your efforts. :) – Japan Trivedi May 22 '12 at 03:39
1

After a week of brain storming I've found the solution myself. I am really happy that finally I have achieved this. :)

For the purpose to validate the dynamically generated fields you need to depend on custom validations on server side. Because if we use the Annotation based validation for dynamically generated fields then after validation it will not come in the controller function.

So whenever you do custom validations then the validation will be called from the controller function. And there you can generate error on dynamically generated fields in the list.

If validation is not successful then you need to get back to the jsp page and display errors on the form. You need to display the dynamically generated field values along with their errors using .

I hope this helps others who also want the same thing to work.

Japan Trivedi
  • 4,445
  • 2
  • 23
  • 44
  • Sorry.. I don't have that code with me now. you can follow what is explained above its pretty simple. Instead of using annotation approach for validating your pojo object, you need to validate the pojo object manually inside your controller function. If validation fails you can set error and display on JSP page. – Japan Trivedi Mar 09 '16 at 14:54