关于java:在Spring MVC中自动生成id

Auto generate id in Spring MVC

我正在尝试保存数据库中的JSP页面收集的数据(Postgres)。 起初我尝试在表单中手动插入任何值(包括id),我在数据库中保存数据没有问题。 现在我正在尝试自动生成id值,但我对如何正确执行它有点困惑。

我的模特 - 产品

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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中的表单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<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>

提交表单时出错

1
2
3
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值。

如何实现自动生成的ID? JPA注释是否是正确的方法?


Now I'm trying to auto generate the id values, but I'm a little bit
confused about how to do it properly

如果要自动生成id,则不要提供一个,即使它是null。 因此,从addProduect方法中删除id

1
2
3
4
@Override
public void addProduct(String description, double price, Date date) {
    jdbcTemplate.update("INSERT INTO products values(?, ?, ?)", description, price, date);
}

此外,请将此id字段auto-increment设为此问题。

或者,更改addProduct方法并使用EntityManager#persist方法:

1
2
3
4
@Override
public void addProduct(Product product) {
    entityManager.persist(product);
}

关于错误:

ERROR: null values in column"id" violates not-null constraint

由于表单不从客户端获取id值,/newproduct端点将具有Product null作为其id值:

1
2
@RequestMapping(value ="/newproduct", method = RequestMethod.POST)
public ModelAndView submitForm(@ModelAttribute("product") Product product) { ... }

然后将此null值作为参数传递给addProduct方法:

1
prDao.addProduct(product.getId(), ...)

最后addProduct会尝试将该null值保存为主键的值,该主键具有非空约束,因此您将收到该错误。

此外,使用实体对象作为与客户端通信的手段,例如, Product,不是一个好习惯。 尝试定义一些辅助抽象,如Forms或DTO,并将它们用于表单处理或响应组装。