I'm trying to save data collected by a JSP page within a database (Postgres). At first I tried to insert any values manually (including id
) in a form and I had no problem saving the data in my db. Now I'm trying to auto generate the id
values, but I'm a little bit confused about how to do it properly.
My model - Product
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String description;
private double price;
@DateTimeFormat(pattern = "dd/MM/yyyy")
private Date date;
public Product() { }
public Product(Long id, String description, double price, Date date) {
this.id = id;
this.description = description;
this.price = price;
this.date = date;
}
//getters and setters
}
My controller - DBConnection
@Controller
public class DBConnection {
@Autowired
private ProductDao prDao;
@RequestMapping(value = "/newproduct", method = RequestMethod.GET)
public ModelAndView showForm() {
Product product = new Product();
return new ModelAndView("newproduct", "product", product);
}
@RequestMapping(value = "/newproduct", method = RequestMethod.POST)
public ModelAndView submitForm(@ModelAttribute("product") Product product) {
ModelAndView mav = new ModelAndView();
prDao.addProduct(product.getId(), product.getDescription(), product.getPrice(), product.getDate());
mav.setViewName("product");
mav.addObject("product", product);
return mav;
}
}
ProductDaoImpl
public class ProductDaoImpl implements ProductDao {
private DataSource dataSource;
private JdbcTemplate jdbcTemplate;
@Override
public void setDataSource(DataSource ds) {
this.dataSource = ds;
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
@Override
public void addProduct(Long id, String description, double price, Date date) {
jdbcTemplate.update("INSERT INTO products values(?, ?, ?, ?)", id, description, price, date);
}
}
My form in newproduct.jsp
<form:form method="POST" action="newproduct" modelAttribute="product">
<table>
<tr>
<td><form:label path="description">Description</form:label></td>
<td><form:input path="description" /></td>
</tr>
<tr>
<td><form:label path="price">Price</form:label></td>
<td><form:input path="price" /></td>
</tr>
<tr>
<td><form:label path="date">Date (dd/mm/yyyy)</form:label></td>
<td><form:input path="date" /></td>
</tr>
<tr>
<td><input type="submit" value="Submit" /></td>
</tr>
</table>
</form:form>
Error when I submit the form
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [INSERT INTO products values(?, ?, ?, ?)]; ERROR: null values in column "id" violates not-null constraint
Detail: The row contains error (null, nnvfe, 10.00, 2010-10-10).; nested exception is org.postgresql.util.PSQLException: ERROR: null values in column "id" violates not-null constraint
Detail: The row contains error (null, nnvfe, 10.00, 2010-10-10).
I think the problem is in the addProduct
method: the id
value isn't yet created when I tried to get it.
How can I implements an auto generated id? Is the JPA annotation the correct way to do that thing?
Now I'm trying to auto generate the id values, but I'm a little bit confused about how to do it properly
If you want to automatically generate the id
, then do not provide one, even it's null
. So, remove the id
from addProduect
method:
@Override
public void addProduct(String description, double price, Date date) {
jdbcTemplate.update("INSERT INTO products values(?, ?, ?)", description, price, date);
}
Also, make your id
field auto-increment
, as in this question.
Or, change the addProduct
method and use EntityManager#persist
method:
@Override
public void addProduct(Product product) {
entityManager.persist(product);
}
About the error:
ERROR: null values in column "id" violates not-null constraint
Since your form does not take the id
value from the client, the /newproduct
endpoint would have a Product
with null
as its id
value:
@RequestMapping(value = "/newproduct", method = RequestMethod.POST)
public ModelAndView submitForm(@ModelAttribute("product") Product product) { ... }
Then you pass this null
value as the parameter to the addProduct
method:
prDao.addProduct(product.getId(), ...)
And finally addProduct
would try to save that null
value as the value of the Primary Key, which has a Non-Null constraint, so you're got that error.
Also, using Entity objects as the means of communication with client, e.g. Product
, is not a good practice. Try to define some auxiliary abstractions like Forms or DTOs and use them for form handling or response assembling.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With