问题描述
我正在尝试将JSP页面收集的数据保存在数据库中(Postgres)。最初,我尝试在表单中手动插入任何值(包括 id
),并且将数据保存在数据库中没有问题。现在,我尝试自动生成 id
值,但是我对如何正确执行操作有些困惑。
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.
我的模型-产品
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
}
我的控制器-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);
}
}
我在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>
错误,当我提交表单
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).
我认为问题出在 addProduct
方法: id
值在我尝试获取时尚未创建。
I think the problem is in the addProduct
method: the id
value isn't yet created when I tried to get it.
如何实现自动生成的ID? JPA批注是执行此操作的正确方法吗?
How can I implements an auto generated id? Is the JPA annotation the correct way to do that thing?
推荐答案
如果要自动生成 id
,然后不提供,即使它是 null
。因此,从 addProduect
方法中删除 id
:
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);
}
另外,输入您的 id
字段自动递增
,如此 。
Also, make your id
field auto-increment
, as in this question.
或者,更改 addProduct
方法并使用 EntityManager#persist
方法:
Or, change the addProduct
method and use EntityManager#persist
method:
@Override
public void addProduct(Product product) {
entityManager.persist(product);
}
关于错误:
不从客户端获取 id
值, / newproduct
端点将具有 Product
以 null
作为其 id
值:
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) { ... }
然后您通过此 null
值作为 addProduct
方法的参数:
Then you pass this null
value as the parameter to the addProduct
method:
prDao.addProduct(product.getId(), ...)
最后是 addProduct
会尝试将 null
的值保存为主键的值,该键具有 Non-Null 约束,所以您会遇到错误
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.
此外,还使用 Entity 对象作为与客户端进行通信的手段,例如产品
,不是一个好习惯。尝试定义一些辅助抽象,例如Forms或DTO,并将其用于表单处理或响应组装。
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.
这篇关于在Spring MVC中自动生成ID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!