Getting all the time: Invalid property of bean class: Bean property is not readable - spring-boot

I always get this error, nonetheless whether I create the getter/setter manually or doing it via Lombok.
So, I guess the error has nothing to do with the Getters/Setters but I cannot find the answer to my problem.
This is my error message:
Invalid property 'person' of bean class [java.util.ArrayList]: Bean property 'person' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
This is my Enttiy class:
#Data
#Getter
#Setter
#Entity
#Table(name="incomeoutgo", schema = "public")
public class IncomeOutgo extends AbstractPersistable<Long> {
#Version
#NotNull
#Column(name ="id")
private Long id;
#Column(name="dayofweek")
private Date dayofweek;
#Column(name="location")
private String location;
#Size(min = 5, max = 50)
#Column(name ="person")
private String person;
#Min(0)
#Column(name ="version")
private Integer version;
#Column(name="income")
private int income;
#Column(name="outgo")
private int outgo;
}
And this is my Controller class
#RequiredArgsConstructor
#Controller
#RequestMapping(value = "/incomeoutgo")
public class IncomeOutgoController {
private static final String INCOMEOUTGO_VIEW = "incomeoutgo";
private final IncomOutgoService incomeoutgoService;
#GetMapping
public String showShop(Model model) {
List<IncomeOutgo> incomeOutgoList = incomeoutgoService.getIncomeOutgoList();
model.addAttribute(INCOMEOUTGO_VIEW, incomeOutgoList);
return INCOMEOUTGO_VIEW;
}
#PostMapping("/incomeoutgo")
public String addUser(#ModelAttribute("incomeoutgo") IncomeOutgo incomeoutgo, BindingResult bindingResult) {
incomeoutgoService.addIncomeOutgo(incomeoutgo);
return "incomeoutgo";
}
}
And last but not least my Thymeleaf template:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Incomes / Expenses</title>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
<body>
<table>
<tr>
<th>Id</th>
<th>Day of Week</th>
<th>Name</th>
<th>Location</th>
<th>Income</th>
<th>Expense</th>
</tr>
<tr th:each="incomeoutgo : ${incomeoutgo}">
<td th:text="${incomeoutgo.id}">id</td>
<td th:text="${incomeoutgo.dayofweek}">dayofweek</td>
<td th:text="${incomeoutgo.person}">person</td>
<td th:text="${incomeoutgo.location}">location</td>
<td th:text="${#numbers.formatCurrency(incomeoutgo.income)}">"${#numbers.formatCurrency(incomeoutgo.income)}"</td>
<td th:text="${#numbers.formatCurrency(incomeoutgo.outgo)}">"${#numbers.formatCurrency(incomeoutgo.outgo)}"</td>
</tr>
</table>
<form action="#" th:action="#{/incomeoutgo}" th:object="${incomeoutgo}" method="post">
<table>
<tr>
<td>Name:</td>
<td><input type="text" th:field="*{person}" /></td>
<td th:if="${#fields.hasErrors('person')}" th:errors="*{person}">Name Error</td>
</tr>
<tr>
<td><button type="submit">Submit</button></td>
</tr>
</table>
</form>
</body>
</html>

The error is explained: Invalid property 'person' of bean class [java.util.ArrayList]. You're trying to call getPerson() on a java.util.ArrayList (which doesn't have that property). I suspect it's in your form:
<form ... th:object="${incomeoutgo}">
You've added incomeoutgo to your model as a List<IncomeOutgo>, but you're trying to treat it as an IncomeOutgo instead. You need to create a single object and use that instead when trying to bind form field values.
model.addAttribute(INCOMEOUTGO_VIEW, incomeOutgoList);
model.addAttribute("page", new IncomeOutgo());
.
.
.
<form ... th:object="${page}">
<input type="text" th:field="*{person}" />
(Side node, reusing the same variable name multiple times makes the code confusing. You have the model attribute ${incomeoutgo}, the temporary loop variable th:each="incomeoutgo : ${incomeoutgo}" and the bound thymeleaf object th:object="${incomeoutgo}" which may or may not be related.)

Related

Display items into Spring MVC table

I have this Endpoint:
#Controller
public class FileImportsController {
private EntityImportRequestsService entityImportRequestsService;
#Autowired
public FileImportsController(EntityImportRequestsService entityImportRequestsService) {
this.entityImportRequestsService = entityImportRequestsService;
}
#GetMapping("/imported_files")
public String viewHomePage(Model model) {
List<EntityImportRequestsTable> listProducts = entityImportRequestsService.findAll();
System.out.println("Size is " + listProducts.size());
model.addAttribute("listProducts", listProducts);
return "index";
}
}
Entity:
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#Builder(toBuilder = true)
#Entity
#Table(name = "EntityImportRequests")
public class EntityImportRequestsTable implements Serializable {
#Id
#Column(name = "requestId")
private String requestId;
#Column(name = "transactionGroupId")
private Integer transactionGroupId;
#Column(name = "requestXmlSourceFile")
private String requestXmlSourceFile;
#Column(name = "createdOn")
private LocalDateTime createdOn;
}
Web page index.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8"/>
<title>Files Manager</title>
</head>
<body>
<div align="center">
<h1>Files List</h1>
<table border="1" cellpadding="10">
<tr th:each="item : ${listProducts}">
<td th:text="${item.requestId}"/>
<td th:text="${item.transactionGroupId}"/>
<td th:text="${item.requestXmlSourceFile}"/>
<td th:text="${item.createdOn}"/>
</tr>
</table>
</div>
</body>
</html>
When I open the page data is not displayed. What is the proper way to display the data rows from listProducts?
When I make a call to the rest controller directly I get this output:
Hibernate: select entityimpo0_.requestId as requesti1_0_, entityimpo0_.createdOn as createdo2_0_, entityimpo0_.requestXmlSourceFile as requestx3_0_, entityimpo0_.transactionGroupId as transact4_0_ from integration.EntityImportRequests entityimpo0_
Size is 69
As you can see the list is not empty. I have 69 items.
Try something like this.
Just make sure that your listProducts is not empty in your controller.
<tr th:each="product: ${listProducts}">
<td th:text="${product.requestId}" />
<td th:text="${product.name}" />
<td th:text="${product.price}" />
</tr>
Or whatever fields your product entity has next to the name, price, etc.

How to work with a many-to-many relationship with extra attributes using Spring Boot, Spring MVC, Spring Data JPA and Thymeleaf

I'm tryingto build an insert, update and delete forms for a many-to-many relationship with one extra attribute, but I'm having some problems. When I use a simple #ManyToMany annotation everything works since Spring MVC and Thyemeleaf automatically take care of everything. Now, I need to have an extra attribute in the join table/entity. This attribute will be managed by the business logic and it doesn't need to be present in the view. I'm implementing my scenario creating manually the join entity rather than using the #Embedded annotation.
What I have so far will be shown below. Note that I'm omitting the import statements and I'm reproducing a very simpler version that I actually have.
Entities
#Entity
#Data
#AllArgsConstructor
#NoArgsConstructor
#EqualsAndHashCode( onlyExplicitlyIncluded = true )
public class Race {
#Id
#GeneratedValue( strategy = GenerationType.IDENTITY )
#EqualsAndHashCode.Include
private Long id;
#NotNull
#NotEmpty
private String name;
#OneToMany( mappedBy = "race", cascade = CascadeType.ALL, orphanRemoval = true )
private Set<TruckFromRace> trucksFromRace;
}
#Entity
#Data
#AllArgsConstructor
#NoArgsConstructor
#EqualsAndHashCode( onlyExplicitlyIncluded = true )
public class Truck {
#Id
#GeneratedValue( strategy = GenerationType.IDENTITY )
#EqualsAndHashCode.Include
private Long id;
#NotNull
#Min( value = 1 )
private Integer number;
#OneToMany( mappedBy = "truck", cascade = CascadeType.ALL, orphanRemoval = true )
private Set<TruckFromRace> trucksFromRace;
}
#Entity
#Data
#AllArgsConstructor
#NoArgsConstructor
#EqualsAndHashCode( onlyExplicitlyIncluded = true )
public class TruckFromRace {
#Id
#GeneratedValue( strategy = GenerationType.IDENTITY )
#EqualsAndHashCode.Include
private Long id;
#ManyToOne
#JoinColumn( name = "truck_id" )
#ToString.Exclude
#JsonProperty( access = Access.WRITE_ONLY )
private Truck truck;
#ManyToOne
#JoinColumn( name = "race_id" )
#ToString.Exclude
#JsonProperty( access = Access.WRITE_ONLY )
private Race race;
#NotNull
private Integer currentLap = 0;
}
Repositories
public interface RaceRepository extends CrudRepository<Race, Long> {
}
public interface TruckFromRaceRepository extends CrudRepository<TruckFromRace, Long> {
}
public interface TruckRepository extends CrudRepository<Truck, Long> {
}
Controller
#Controller
#RequestMapping( "/races" )
public class RaceController {
#Autowired
private RaceRepository raceRepo;
#Autowired
private TruckRepository truckRepo;
#Autowired
private TruckFromRaceRepository trucksFromRaceRepo;
#GetMapping( "/list" )
public String listar( Model model ) {
model.addAttribute( "races", raceRepo.findAll() );
return "/forms/races/list";
}
#GetMapping( "/prepareInsert" )
public String prepareInsert( Race race, Model model ) {
model.addAttribute( "trucks", truckRepo.findAll() );
return "/forms/races/insert";
}
#PostMapping( "/insert" )
public String insert( #Valid Race race,
BindingResult result,
Model model,
#RequestParam( required = false ) Long[] trucksFromRace ) {
if ( result.hasErrors() ) {
model.addAttribute( "trucks", truckRepo.findAll() );
return "/forms/races/insert";
}
raceRepo.save( race );
if ( trucksFromRace != null ) {
for ( Long truckId : trucksFromRace ) {
Truck t = truckRepo.findById( truckId ).get();
TruckFromRace tr = new TruckFromRace();
tr.setTruck( t );
tr.setRace( race );
trucksFromRaceRepo.save( tr );
}
}
return "redirect:/races/list";
}
#GetMapping( "/prepareUpdate/{id}" )
public String prepareUpdate( #PathVariable( "id" ) Long id,
Model model ) {
Race race = raceRepo.findById( id )
.orElseThrow( () -> new IllegalArgumentException( "Invalid id:" + id ) );
model.addAttribute( "trucks", truckRepo.findAll() );
model.addAttribute( "race", race );
return "/forms/races/update";
}
#PostMapping( "/update/{id}" )
public String update( #PathVariable( "id" ) Long id,
#Valid Race race,
BindingResult result,
Model model,
#RequestParam( required = false ) Long[] trucksFromRace ) {
if ( result.hasErrors() ) {
model.addAttribute( "trucks", truckRepo.findAll() );
race.setId( id );
return "/forms/races/update";
}
// remove all trucks from this race
// only works if the if above is commented
race.getTrucksFromRace().clear();
raceRepo.save( race );
// try to associate new ones
/*if ( trucksFromRace != null ) {
for ( Long truckId : trucksFromRace ) {
Truck t = truckRepo.findById( truckId ).get();
TruckFromRace tr = new TruckFromRace();
tr.setTruck( t );
tr.setRace( race );
trucksFromRaceRepo.save( tr );
}
}*/
return "redirect:/races/list";
}
}
Templates
forms/races/list.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<title>Races</title>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no"/>
</head>
<body>
<h4>Races</h4>
<table>
<thead>
<tr>
<th>Name</th>
<th>Update</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
<tr th:each="race : ${races}">
<td th:text="${race.name}"></td>
<td><a th:href="#{/races/prepareUpdate/{id}(id=${race.id})}">Update</a></td>
<td><a th:href="#{/races/prepareDelete/{id}(id=${race.id})}">Delete</a></td>
</tr>
</tbody>
</table>
New Race
<br/>
Index
</body>
</html>
forms/races/insert.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<title>New Race</title>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no"/>
</head>
<body>
<h4>New Race</h4>
<form action="#" th:action="#{/races/insert}" th:object="${race}" method="post">
<div>
<label for="name">Name</label>
<input type="text" th:field="*{name}" id="name" placeholder="Name"/>
<small th:if="${#fields.hasErrors('name')}" th:errors="*{name}"></small>
</div>
<h4>Trucks</h4>
<table>
<thead>
<tr>
<th>Number</th>
<th>Will compete</th>
</tr>
</thead>
<tbody>
<tr th:each="truck : ${trucks}">
<td th:text="${truck.number}"></td>
<td>
<input class="form-check-input" th:field="*{trucksFromRace}" type="checkbox" th:value="${truck.id}"/>
</td>
</tr>
</tbody>
</table>
<input type="submit" value="Save"/>
<br/>
Back
</form>
</body>
</html>
forms/races/update.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<title>New Race</title>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no"/>
</head>
<body>
<h4>Update Race</h4>
<form action="#" th:action="#{/races/update/{id}(id=${race.id})}" th:object="${race}" method="post">
<div>
<label for="name">Name</label>
<input type="text" th:field="*{name}" id="name" placeholder="Name"/>
<small th:if="${#fields.hasErrors('name')}" th:errors="*{name}"></small>
</div>
<h4>Trucks</h4>
<table>
<thead>
<tr>
<th>Number</th>
<th>Will compete</th>
</tr>
</thead>
<tbody>
<tr th:each="truck : ${trucks}">
<td th:text="${truck.number}"></td>
<td>
<input class="form-check-input" th:field="*{trucksFromRace}" type="checkbox" th:value="${truck.id}"/>
</td>
</tr>
</tbody>
</table>
<input type="submit" value="Save"/>
<br/>
Back
</form>
</body>
</html>
My insertion is working fine, althoug I think that the controller code could be simpler, but I have two problems with the update operation. I'm omitting the delete operation because it will be based in the update operation.
When I try to update a race, clicking in the update link in the list of races, the form is being loaded erroneously. Let me explain. Firstly I save a new race and it works as expected:
But, when I try to update it, I have this erroneous result in my view:
So, I would like to know what I need to do to solve this.
My second problem is related to the update method in the RaceController class. What I'm experiencing is described in some comments inside the code. I'm pretty rusty with JPA... My last time doing these kinds of implementations in real scenarios was more than 10 years ago.
Thanks!
Many to many link table only take care of two table in many to many , it may not handle extra attribute.
In my way the possible solution is to create/entity
Which hold two tables and one attribute.
Previous:
Table1 and Table2 in m2m relationship.
Solution
Table 3 has one to many relationship with table 1 and table 2 , also table 3 has an other extra attribute.

How do I bind table values to a Map and post with Spring MVC and Thymeleaf?

I have an entry form where users select a subset of items which populate a table. I need to bind each row's first and and third column value to a key and value, respectively, enter them into a Map<Integer, Integer> passed in through the controller, and post the data. I've poured through many different solutions online and have yet to find one that works. The map always returns empty.
Wrapper class for Map
#Getter #Setter
public class ItemForm {
private Map<Integer, Integer> items = new HashMap<>();
}
Controllers
#GetMapping(...)
public String showItemPage(Model model) {
...
model.addAttribute("itemForm", new ItemForm());
...
}
#PostMapping(...)
public String processItemUpdate(#ModelAttribute("itemForm") ItemForm itemForm, BindingResult bindingResult) {
...
}
Template
<tr th:each="item : *{items}">
<td>
<input type="text" th:value="${item.key}">
</td>
<td></td>
<td>
<input type="text" th:field="*{items[__${item.key}__]}">
</td>
</tr>
I understand that I will need something like th:field="*{items[__${item.key}__]}" to access the map, but as to extracting and combining the key-value pair I'm a bit lost.
edit:
Is something along these lines possible?
#Getter #Setter
public class ItemFormPair {
private int ID, quantity;
}
#Getter #Setter
public class ItemForm {
private List<ItemFormPair> items = new ArrayList<>();
}
<tr th:each="item, stat : *{items}">
<td>
<input type="text" th:field="*{items[__${stat.index}__].ID}">
</td>
<td></td>
<td>
<input type="text" th:field="*{items[__${stat.index}__].quantity}">
</td>
</tr>
edit:
I don't really want to spend any more time on this problem and there doesn't appear to be an elegant solution available so I'm simply going to use an Ajax POST request.
You bound the single key/values of the map to the form but not the map itself. That won't work that way. I'm quite sure there is no way to get the map as whole piece back from the form. Maybe with a converter.
An alternative could be to assign name/id to the input fields and read all key/values back to map in the processItemUpdate method:
This solution works on my site. I redefined my answer more precisely:
input.html
<!DOCTYPE HTML>
<html lang="de" xmlns:th="http://www.thymeleaf.org">
<head />
<body>
<form th:action="#{/inputPost}" method="post" th:fragment="form">
<table>
<tr th:each="item,iter : ${itemForm.items.entrySet()}">
<td><input type="text" th:id="${iter.index + '.ID'}"
th:name="${iter.index + '.ID'}" th:value="${item.key}"></td>
<td><input type="text" th:id="${iter.index + '.VALUE'}"
th:name="${iter.index + '.VALUE'}" th:value="${item.value}"></td>
</tr>
</table>
<input type="submit" name="Send" value="Send" /> <input type="submit"
name="Add" value="Add new Line" />
</form>
</body>
</html>
success.html
<!DOCTYPE HTML>
<html lang="de" xmlns:th="http://www.thymeleaf.org">
<head></head>
<body>
<table border="1">
<tr th:each="item : ${itemForm.items.entrySet()}">
<td th:text="${item.key}"></td>
<td th:text="${item.value}"></td>
</tr>
</table>
</body>
</html>
Controller
#GetMapping("/inputForm")
public String dummy(Model model) {
ItemForm form = new ItemForm();
form.getItems().put(form.getItems().size(), 42);
model.addAttribute("itemForm", form);
return "input";
}
#PostMapping("/inputPost")
public String processItemUpdate(HttpServletRequest request, Model model) {
Map<String, String[]> params = request.getParameterMap();
ItemForm form = new ItemForm();
String operation = null;
for (Entry<String, String[]> entry : params.entrySet()) {
if (entry.getKey().endsWith(".ID")) { // only react on ID values. The values will be directly fetched from
// map
String[] tokens = StringUtils.split(entry.getKey(), ".");
Integer id = Integer.parseInt(tokens[0]);
Integer idValue = Integer.parseInt(entry.getValue()[0]);
String[] value = params.get(id + ".VALUE"); // fetch the value to defined ID
Integer valueValue = Integer.parseInt(value[0]);
form.getItems().put(idValue, valueValue);
} else if (entry.getKey().equalsIgnoreCase("Send")) { // determine operation
operation = "send";
} else if (entry.getKey().equalsIgnoreCase("Add")) { // determine operation
operation = "add";
}
}
model.addAttribute("itemForm", form);
if (operation.equals("add")) { // add a new line and resend form again
form.getItems().put(form.getItems().size(), 42);
return "input";
}
return "success";
}

How do I bind a table in a form to a HashSet in Spring Boot?

I am not quite sure how to approach this problem. I have a table rendered by datatables populated with product information. I am trying to figure out a form where I can insert the quantity and discount values and then save either the selected fields or fields where the quantity > 0. Then bind the table data to a set or a list.
However, I am not quite sure how to write the bindings. I have read over this question here but it didn't seem quite the same in that I don't think I could use an index as there could a large amount of products and therefore potentially a large amount of nulls in the response. Any help would be appreciated.
Product.java
#Entity
#Table(name="products")
public class Product {
#Getter
#Setter
#Id
private Long productId;
#Getter
#Setter
private Long productName;
}
QuoteForm.java
public class QuoteForm {
#Getter
#Setter
private Long quoteId;
#Getter
#Setter
private Long contactId;
#Getter
#Setter
private Set<ProductEntry> products;
}
ProductEntry.java
public class ProductEntry {
#Getter
#Setter
private TempProduct product;
#Getter
#Setter
private Long quantity;
#Getter
#Setter
private float discount;
}
form.html
<form id="productTable" th:object="${quoteForm}">
<input type="number" th:field="*{contactId}"></input>
<table id ="productList"
class="table table-striped table-bordered"
cellspacing="0"
width="100%">
<thead>
<tr>
<th>Name</th>
<th>Quantity</th>
<th>Discount</th>
</tr>
</thead>
<tbody>
<tr th:each="product : ${productData.getProducts()}">
<td name="?">
<a th:text="${product.getProductName()}"
th:href="#{|/product/records/${product.getProductId()}|}">
</a>
</td>
<td>
<input type="number"
name="?"
th:field="*{products.quantity}">
</input>
</td>
<td>
<input type="number" name="?" th:field="*{products.discount}"></input>
</td>
</tr>
</tbody>
You can do binding using "model.addAttribute()". Something like this in your controller:
#RequestMapping("/example")
public String formParse(Model model) {
//some logic
Set<ProductEntry> productList = //code to get();
model.addAttribute("productList", productList);
//some more logic
return "yourView";
}
Here "productList" is the name which you have assigned to "?".
And as for checking the quantity you can do that in the form itself, with some thing like:
<div th:if="*{products.quantity>0}" th:field="*{products.quantity}"></div>
Here &gt represents "greater than".
Hope this helps!

Spring form validation - errors are not displayed

I have following situation:
I try to create a simple form to edit information about a movie. Therefor I use spring mvc with jsp.
For the validation I use the JSR 303 hibernate implementation (hibernate-validator 4.2.0).
My problem is that if there are validation errors (BindResults hasErrors method returns true) I can only display the errors with
<form:errors path="*" />
and not fieldspecific. like with:
<form:errors path="title" />
I have no idea why but all errors are displayed in at the path="*" errortag, but none at the fieldspecific ones. The only errors which are displayed right to the field are some which brought an exception i.e.
Failed to convert property value of type java.lang.String to required type int for property runtime; nested exception is java.lang.NumberFormatException: For input string: "")
the important parts of my jsp file look like this:
<%# taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<form:form commandName="movie">
<fieldset>
<form:errors path="*" cssClass="formErrorBlock"/>
<table>
<tr>
<td><form:label path="title">Title:</form:label></td>
<td>
<form:input path="title"/>
<form:errors path="title" cssClass="formFieldError"/>
</td>
</tr>
<tr>
<td><form:label path="runtime">Runtime:</form:label></td>
<td>
<form:input path="runtime"/><br />
<form:errors path="runtime" cssClass="formFieldError" />
</td>
</tr>
<tr>
<td><form:label path="imdbId">IMDB-ID:</form:label></td>
<td>
<form:input path="imdbId"/><br />
<form:errors path="imdbId" cssClass="formFieldError" />
</td>
</tr>
<tr>
<td></td>
<td>
<input type="submit" />
</td>
</tr>
</table>
</fieldset>
</form:form>
My Controller:
#Controller
public class MovieController {
#Autowired
private MovieService _movieService;
//some other methods...
#RequestMapping(value="/movie/{pMovieId}/edit", method = RequestMethod.GET)
public String showForm(ModelMap pModel, #PathVariable Integer pMovieId) {
Movie movie = _movieService.getMovieById(pMovieId);
pModel.addAttribute("movie", movie);
return "edit/movie";
}
#RequestMapping(value="/movie/{pMovieId}/edit", method = RequestMethod.POST)
public String editMovieSave(#Valid Movie pMovie, BindingResult pResult, #PathVariable Integer pMovieId, ModelMap pModel) {
Movie movie = _movieService.getMovieById(pMovieId);
if(pResult.hasErrors()) {
return "edit/movie";
}
//save
//redirect to moviepage
return "redirect:/movie/" + pMovieId;
}
}
and finally my movie class:
public class Movie implements Serializable{
private int _id;
#NotEmpty
#Size(min=3)
private String _title;
#NotEmpty
private String _filename;
#Pattern(regexp="tt+[0-9]{7}")
private String _imdbId;
#Min(value=1)
private int _runtime;
//getters and setters....
}
I know this question has been asked a lot of times before, but none of the answers worked with me.
thanks for your help
I solved it by renaming the attributes (removing the underlines). However it was like "jpprade" said (maybe there are accessed by reflection).
For those who can't rename the class attributes (in case of some codingconventions, ...) can annotate the getter methods.

Resources