Java 在 Spring MVC 中自动生成 id

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36388919/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 17:48:48  来源:igfitidea点击:

Auto generate id in Spring MVC

javaspringpostgresqljpa

提问by andy

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 idvalues, but I'm a little bit confused about how to do it properly.

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

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

我的控制器 - 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

产品道Impl

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

我在 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>

Errorwhen 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 addProductmethod: the idvalue isn't yet created when I tried to get it.

我认为问题出在addProduct方法上:id当我尝试获取它时,该值尚未创建。

How can I implements an auto generated id? Is the JPA annotation the correct way to do that thing?

如何实现自动生成的 id?JPA 注释是做这件事的正确方法吗?

采纳答案by Ali Dehghani

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

现在我正在尝试自动生成 id 值,但我对如何正确执行有点困惑

If you want to automatically generate the id, then do not provide one, even it's null. So, remove the idfrom addProduectmethod:

如果你想自动生成id,那么不要提供一个,即使是null. 因此,删除idfromaddProduect方法:

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

Also, make your idfield auto-increment, as in this question.

另外,让你的id领域auto-increment,如在这个问题中

Or, change the addProductmethod and use EntityManager#persistmethod:

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

@Override
public void addProduct(Product product) {
    entityManager.persist(product);
}

About the error:

关于错误:

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

错误:“id”列中的空值违反了非空约束

Since your form does not take the idvalue from the client, the /newproductendpoint would have a Productwith nullas its idvalue:

由于您的表单不id从客户端获取值,因此/newproduct端点将使用Productwithnull作为其id值:

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

Then you pass this nullvalue as the parameter to the addProductmethod:

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

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

And finally addProductwould try to save that nullvalue as the value of the Primary Key, which has a Non-Nullconstraint, so you're got that error.

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

Also, using Entityobjects 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.

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