添加产品时的org.hibernate.exception.ConstraintViolationException

时间:2017-11-30 15:27:35

标签: hibernate spring-mvc h2

因此,当我想从前端表单向数据库添加产品时,会发生以下错误:

Nov 30, 2017 8:28:54 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: NULL not allowed for column "ID"; SQL statement:
insert into Product (id, category_id, price, productDescription, productname, quantity) values (null, ?, ?, ?, ?, ?) [23502-196]
Nov 30, 2017 8:28:54 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/project1_frontend] threw exception [Request processing failed; nested exception is org.hibernate.exception.ConstraintViolationException: NULL not allowed for column "ID"; SQL statement:
insert into Product (id, category_id, price, productDescription, productname, quantity) values (null, ?, ?, ?, ?, ?) [23502-196]] with root cause
org.h2.jdbc.JdbcSQLException: NULL not allowed for column "ID"; SQL statement:
insert into Product (id, category_id, price, productDescription, productname, quantity) values (null, ?, ?, ?, ?, ?) [23502-196]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
    at org.h2.message.DbException.get(DbException.java:179)
    at org.h2.message.DbException.get(DbException.java:155)
    at org.h2.table.Column.validateConvertUpdateSequence(Column.java:345)
    at org.h2.table.Table.validateConvertUpdateSequence(Table.java:797)
    at org.h2.command.dml.Insert.insertRows(Insert.java:151)
    at org.h2.command.dml.Insert.update(Insert.java:114)
    at org.h2.command.CommandContainer.update(CommandContainer.java:101)
    at org.h2.command.Command.executeUpdate(Command.java:260)
    at org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(JdbcPreparedStatement.java:164)
    at org.h2.jdbc.JdbcPreparedStatement.executeUpdate(JdbcPreparedStatement.java:150)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:122)
    at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
    at com.sun.proxy.$Proxy43.executeUpdate(Unknown Source)
    at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:96)
    at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:55)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2757)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3268)
    at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:78)
    at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:272)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:304)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:195)
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:128)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:204)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:189)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:114)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
    at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:615)
    at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:608)
    at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:604)
    at com.niit.dao.ProductDaoImpl.saveOrUpdateProduct(ProductDaoImpl.java:45)
    at com.niit.services.ProductServiceImpl.saveOrUpdateProduct(ProductServiceImpl.java:31)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:280)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
    at com.sun.proxy.$Proxy38.saveOrUpdateProduct(Unknown Source)
    at com.niit.controllers.ProductController.saveorUpdateProduct(ProductController.java:86)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:475)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:651)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:500)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:754)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1376)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)

产品类:

package com.niit.product;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.validation.constraints.Min;

import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.web.multipart.MultipartFile;



@Entity
public class Product {
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO) //Automatically generate value for Id using sequence
private int id; //product.setId(0)

@NotEmpty(message="Product name is mandatory")
private String productname;//product.setProductName("pen")
@NotEmpty(message="Product description cannot be blank")
private String productDescription;

private int quantity;
@Min(value=10,message="Minimum price is 10")
private double price;
@ManyToOne
private Category category;//product.setCategory().setId(1)
@Transient
private MultipartFile image; //image will not get persisted in the table
public int getId() {
    return id;
}
public void setId(int id) {
    this.id = id;
}
public String getProductname() {
    return productname;
}
public void setProductname(String productname) {
    this.productname = productname;
}
public int getQuantity() {
    return quantity;
}
public void setQuantity(int quantity) {
    this.quantity = quantity;
}
public double getPrice() {
    return price;
}
public void setPrice(double price) {
    this.price = price;
}
public String getProductDescription() {
    return productDescription;
}
public void setProductDescription(String productDescription) {
    this.productDescription = productDescription;
}
public Category getCategory() {
    return category;
}
public void setCategory(Category category) {
    this.category = category;
}
public MultipartFile getImage() {
    return image;
}
public void setImage(MultipartFile image) {
    this.image = image;
}


}

ID为PK的Category类,作为Product类的category_id或FK:

package com.niit.product;

import java.util.List;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;

@Entity
public class Category {
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
private int id;
private String categoryname;
@OneToMany(mappedBy="category")
private List<Product> products;
public int getId() {
    return id;
}
public void setId(int id) {
    this.id = id;
}
public String getCategoryname() {
    return categoryname;
}
public void setCategoryname(String categoryname) {
    this.categoryname = categoryname;
}

}

这是我的ProductController:

package com.niit.controllers;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.niit.product.Category;
import com.niit.product.Product;
import com.niit.services.ProductService;
@Controller
public class ProductController {
    @Autowired
private ProductService productService;
    @RequestMapping(value="/all/getallproducts")
public ModelAndView getAllProducts(){
    List<Product> products=productService.getAllProducts();
    //productlist - logical view name [productlist.jsp]
    //products - model attribute [use this attribute in jsp]
    //products - List<Product> data 
    return new ModelAndView("productlist","productsAttr",products);
    //JSTL and EL 
}
    // all/viewproduct/1  [id=1]
    @RequestMapping(value="/all/viewproduct/{id}")
    public ModelAndView getProduct(@PathVariable int id){
        Product product=productService.getProduct(id);
        return new ModelAndView("viewproduct","product",product);
    }
    @RequestMapping(value="/admin/deleteproduct/{id}")
    public String deleteProduct(HttpServletRequest request,@PathVariable int id){
        String rootDirectory=request.getServletContext().getRealPath("/");
        Path path=Paths.get(rootDirectory + "/WEB-INF/resources/images/"+id+".png");
        if(Files.exists(path)){
            try {
                Files.delete(path);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        productService.deleteProduct(id);
        return "redirect:/all/getallproducts";
    }
    @RequestMapping(value="/admin/getproductform")
    public String getProductForm(@RequestParam(required=false)int id,Model model){
        if(id==0)//add product
        model.addAttribute("product",new Product());//1
        else{ //edit product
            Product product=productService.getProduct(id);//select * from product where id=?
            model.addAttribute("product",product);
        }
        //SELECT * from Category
        List<Category> categoriesList=productService.getAllCategories();
        model.addAttribute("categories",categoriesList);
        return "productform";
    }
    @RequestMapping(value="/admin/saveorupdateproduct")
    public String saveorUpdateProduct(HttpServletRequest request,@Valid @ModelAttribute(name="product")  Product product,BindingResult result,Model model) {//3
        if(result.hasErrors()){//constraint violation
            List<Category> categories=productService.getAllCategories();
            model.addAttribute("categories",categories);
            return "productform";
        }
        System.out.println(product.getProductname());

        productService.saveOrUpdateProduct(product); //insert and update
        String rootDirectory=request.getServletContext().getRealPath("/");
        System.out.println(rootDirectory);
        Path path=Paths.get(rootDirectory + "/WEB-INF/resources/images/"+product.getId()+".png");
        MultipartFile prodImage=product.getImage();//uploaded image [jpeg,gif,..]
        try {
            prodImage.transferTo(new File(path.toString()));
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }//transfer the image to the file named productid.png
        return "redirect:/all/getallproducts";
    }

}

当我们动态地通过前端添加更多产品时,AUTO生成的策略是否应该自动为产品类生成id?(而不是遇到另一个产品条目的空值)我是hibernate的新手,任何帮助将不胜感激!

Here is my product table at backend H2

1 个答案:

答案 0 :(得分:0)

关注Auto Generation issue并关注此链接,如果其抛出违规异常,那么因为您已在Product表中包含具有这些ID值的条目。

我认为您正在进行开发,因此从数据库中删除条目并从头开始,生成类型为Table。可能是生成类型自动不适用于H2。