I have this model -
public class Product implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@NotBlank
@Column(length = 500, nullable = false)
private String name;
@Column(nullable = false)
private double buyingPrice;
//getters and setters
}
These are the two controller methods responsible for edit/update product
-
@Controller
@RequestMapping("/product")
@SessionAttributes("product")
public class ProductController {
@GetMapping(value = "/edit")
public String edit(@RequestParam("id") int id, ModelMap model) {
Product product = productService.getById(id);
model.put("product", product);
return PRODUCT_EDIT_PAGE;
}
@PostMapping(value = "/edit")
public String update(@Valid @ModelAttribute("product") Product product,
BindingResult result,
ModelMap model) {
//I get `product.getName()` here
if (result.hasErrors()) {
//no matter what I set product name in the edit page
//`BindingResult` always has this error -
//[Field error in object 'product' on field 'name': rejected value [null] ...];
model.put("product", product);
return PRODUCT_EDIT_PAGE;
}
productService.save(product);
return "redirect:/product/list";
}
}
This is the edit page -
<form:form method="POST" modelAttribute="product">
<form:input type="text" path="name"/>
<form:errors path="name"/>
<form:input type="number" path="buyingPrice"/>
<form:errors path="buyingPrice"/>
<button type="submit">
</form:form>
No matter what I set product name in the edit page BindingResult
always has this error -
[Field error in object 'product' on field 'name': rejected value [null]; codes [NotBlank.product.name,NotBlank.name,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [product.name,name]; arguments []; default message [name]]; default message [must not be blank]]
Even though I get product.getName()
in the POST
controller method!
This weird behavior is occurring only when updating an existing product not when creating a new product.
Update 1:
I noticed while debugging that in the post method @ModelAttribute
gets a hibernate proxy object of Product
. A hibernate interceptor [ByteBuddyInterceptor
] is intercepting the request. I guess this might be the issue.
Update 2:
My service class -
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
public Product getById(int id) {
return productRepository.getOne(id);
}
}
My Repository -
public interface ProductRepository extends JpaRepository<Product, Integer> {
List<Product> getAllByUser(User user);
}