3

My project based on spring boot,Thymeleaf,mysql,html and Jquery.

I tried to post a List of EntSetCharges type data to the @controller ,but it is not succeed..it trows error like

java.lang.IllegalStateException: No primary constructor found for java.util.List

Previously i worked with this error org.springframework.expression.spel.SpelEvaluationException: EL1007E: Property or field 'chargesName' cannot be found on null

Now i got another error in same page

Here is my full code...

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
 <!-- bootstrap css lib --> 
      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body>
 <!-- Bootstrap/Jquery CDN library files -->
 <script src="https://code.jquery.com/jquery-3.2.1.js"></script>
 <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
 <!-- External JQuery Script -->
 <!-- <script type="text/javascript" src="../js/formjs/setchargesform.js"></script> -->
 
<!-- Body Content Goes Here --> 
  <div class="container">
 <form method="post" th:object="${tempEntSetChargesList}" th:action="@{/updatesetcharges}">
 <div class="table-responsive"> 
 
 <table class="table table-hover">
 <thead>
     <tr>
      <th>Charge Name</th>
      <th>Amount</th>
      <th>Charge/Unit Type</th>
    </tr>
    </thead>
    
    <tbody>
    <tr th:each="savedcharges:${savedchargeslist}">
      <td id="colhide" hidden="true">
      <label th:value="${savedcharges.pkSetCharges}" th:field="*{pkSetCharges}"></label>
      </td>
      
      <td>
      <label th:text="${savedcharges.chargesName}" th:value="${savedcharges.chargesName}" th:field="*{chargesName}"></label>
      </td>
      
      <td>
      <input id="amt1" class="form-control" th:field="*{tempUnitAmount}">
      </td>
      
      <td>
  <select id="societyname" class="form-control" th:field="*{tempunitType}">
  <option value="perFlat" selected="selected">perFlat</option>
  <option value="perUnit">perUnit</option>
  <option value="perSqrft">perSqrft</option>
  </select>
      </td>
    </tr>
    </tbody>
    
 </table>
 </div>
 
 <button type="submit" class="btn btn-info">Submit</button>
 <button type="reset" class="btn btn-warn">Reset</button>
 </form>
 </div>
 <!-- Body content finishes -->
</body>
</html>

@RestController

@PostMapping(value="/updatesetcharges")
    public ModelAndView doUpdateSetCharges(@ModelAttribute List<EntSetCharges> tempEntSetChargesList)
    {
        ModelAndView respondResult = new ModelAndView();
        try {
            List<EntSetCharges> entSetChargesList = new ArrayList<>();
            for(EntSetCharges ent : tempEntSetChargesList)
            {
                if(ent.getTempunitType().equals("perFlat"))
                {
                    ent.setPerFlat(Integer.parseInt(ent.getTempUnitAmount()));
                }
                else if(ent.getTempunitType().equals("perUnit"))
                {
                    ent.setPerUnit(Double.parseDouble(ent.getTempUnitAmount()));
                }
                else 
                {
                    ent.setPerSqrft(Double.parseDouble(ent.getTempUnitAmount()));
                }
                entSetChargesList.add(ent);
            }

            Boolean result = serSetCharges.doUpdateSetCharges(entSetChargesList);

        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        return respondResult;
    }

Entity

@Entity
@Table(name="setcharges")
public class EntSetCharges implements Serializable
{

/**
 * 
 */
private static final long serialVersionUID = 3827507518731160293L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="pksetcharges")
private int pkSetCharges;

@Column(nullable=false)
private String chargesName;
@ColumnDefault("0")
private int perFlat;
@ColumnDefault("0")
private double perUnit;
@ColumnDefault("0")
private double perSqrft;

@Version
private int version;
private Boolean is_active;
private String created_by;
private Date created_ts;
private String modified_by;
private Date modified_ts;
private String approved_by;
private Date approved_ts;

@Transient
private String tempunitType;

@Transient
private String tempUnitAmount;

@Transient
private LogEntSetCharges tempLogEntSetCharges;

Code UPDATE V1 Here i made some changes it is hitting the Controller page,but there object is EMPTY [] ..Here is Proof of Image Here is the Error Proof v1 @RestController

@PostMapping(value="/updatesetcharges")
    public ModelAndView doUpdateSetCharges(@ModelAttribute WrpSetCharges tempEntSetChargesList)
    {
        ModelAndView respondResult = new ModelAndView();
        try {
            List<EntSetCharges> entSetChargesList = new ArrayList<>();

            for(EntSetCharges ent : tempEntSetChargesList.getTempEntSetChargesList())
            {   //logics goes here

in HTML

<form id="setchargesformid" method="post" th:object="${tempEntSetChargesList}" th:action="@{/updatesetcharges}">

Wrapper class

public class WrpSetCharges {

private List<EntSetCharges> tempEntSetChargesList = new ArrayList<>();

public List<EntSetCharges> getTempEntSetChargesList() {
    return tempEntSetChargesList;
}

public void setTempEntSetChargesList(List<EntSetCharges> tempEntSetChargesList) {
    this.tempEntSetChargesList = tempEntSetChargesList;
}

}
Vignesh R
  • 201
  • 5
  • 8
  • 18

2 Answers2

12

In my case, I use @RequestBody to mapping the input to my model. So it would be

@PostMapping(value="/updatesetcharges")
public ModelAndView doUpdateSetCharges(@RequestBody List<EntSetCharges> tempEntSetChargesList){ 
// Do your stuff and dont forget return
   return new ModelAndView();
}

And also dont forget to add empty constructor in your entity.

3

Put your list in a wrapper class and use that class as your ModelAttributes

class ListWrapper{
     List<EntSetCharges> tempEntSetChargesList;

     public List<EntSetCharges> getTempEntSetChargesList() {
         return tempEntSetChargesList;
     }

     public void setTempEntSetChargesList(List<EntSetCharges> tempEntSetChargesList) {
         this.tempEntSetChargesList = tempEntSetChargesList;
     }
 }

and search here on how to bind list of objects in thymeleaf. ex. how-to-bind-an-object-list-with-thymeleaf below example of binding items in your list.

<tbody>
<tr th:each="currentClient, stat : *{clientList}">
   <td>
      <input type="checkbox" th:field="*{clientList[__${stat.index}__].selected}" />
      <input type="hidden" th:field="*{clientList[__${stat.index}__].clientID}" />
      <input type="hidden" th:field="*{clientList[__${stat.index}__].ipAddress}" />
      <input type="hidden" th:field="*{clientList[__${stat.index}__].description}" />
   </td>
   <td th:text="${currentClient.getClientID()}"></td>
   <td th:text="${currentClient.getIpAddress()}"></td>
   <td th:text="${currentClient.getDescription()}"></td>               
</tr>
</tbody>
joseph
  • 127
  • 4
  • can u please explain reason? – Vignesh R Nov 21 '17 at 12:33
  • 1
    Spring will call the default no args constructor of your ModelAttributes class, in your case your using List interface with no constructor. and Its not good idea using List or any of its implementation as direct request model. – joseph Nov 21 '17 at 12:41
  • now i created a wrapper class ,now it hitting the controller,But the inside of the object is "EMPTY" [ ]...any thing i need to do changes in HTML? – Vignesh R Nov 21 '17 at 13:43
  • it means that the item on your list are not properly bind, can you show your updated view template – joseph Nov 21 '17 at 13:49
  • use input field to bind items in your list, but if you don't want to show an input field in your view you can set it hidden. see for link for example https://stackoverflow.com/questions/36500731/how-to-bind-an-object-list-with-thymeleaf – joseph Nov 21 '17 at 13:57
  • (1)i need to mention wrapper class name to th:object="{wrapper}" or th:object="{tempEntSetChargesList}" ? (2)what i need to mention in th:feild? like "{wrappername.listname.column_name}" or {listname.column_name} – Vignesh R Nov 22 '17 at 04:37
  • org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'chargesName' cannot be found on object of type 'java.util.ArrayList' - maybe not public? – Vignesh R Nov 22 '17 at 07:11