简体   繁体   English

在 Spring MVC 中自动生成 id

[英]Auto generate id in Spring MVC

I'm trying to save data collected by a JSP page within a database (Postgres).我正在尝试将 JSP 页面收集的数据保存在数据库(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.起初,我尝试在表单中手动插入任何值(包括id ),并且将数据保存在我的数据库中没有问题。 Now I'm trying to auto generate the id values, but I'm a little bit confused about how to do it properly.现在我正在尝试自动生成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 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我在 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.我认为问题出在addProduct方法中:当我尝试获取它时,还没有创建id值。

How can I implements an auto generated id?如何实现自动生成的 id? Is the JPA annotation the correct way to do that thing? 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 值,但我对如何正确执行它有点困惑

If you want to automatically generate the id , then do not provide one, even it's null .如果要自动生成id ,则不要提供,即使它是null So, remove the id from addProduect method:因此,从addProduect方法中删除id

@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 .另外,使您的id字段auto-increment ,如在此问题中。

Or, change the addProduct method and use EntityManager#persist method:或者,更改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 id value from the client, the /newproduct endpoint would have a Product with null as its id value:由于您的表单不从客户端获取id值,因此/newproduct端点将有一个带有null作为其id值的Product

@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:然后将此null值作为参数传递给addProduct方法:

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.最后addProduct会尝试将该null值保存为Primary Key的值,该值具有Non-Null约束,因此您会遇到该错误。

Also, using Entity objects as the means of communication with client, eg Product , is not a good practice.此外,使用Entity对象作为与客户端通信的手段,例如Product ,不是一个好的做法。 Try to define some auxiliary abstractions like Forms or DTOs and use them for form handling or response assembling.尝试定义一些辅助抽象,如 Forms 或 DTO,并将它们用于表单处理或响应组装。

Error-Caused by: java.sql.SQLSyntaxErrorException: Specified key was too long; max key length is 1000 bytes 

operation perform-
@Id
private String userName;

Solution解决方案

  1. Go to mysql database进入mysql数据库
  2. Go to schema setting转到架构设置
  3. change Default charset to latin1将默认字符集更改为 latin1
  4. Run on server your spring mvc program step在服务器上运行你的 spring mvc 程序步骤
  5. Finally Your table is created with @Id on String最后,您的表是使用 String 上的 @Id 创建的

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM