title: org.hibernate.exception.ConstraintViolationException on add product
body: <p>So when I wanted to add a product to the database from the frontend form and the following error occurs : </p>
  
  <pre><code>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)
  </code></pre>
  
  <p>The Product class :</p>
  
  <pre><code>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;
  }
  
  
  }
  </code></pre>
  
  <p>The Category class for which the id is PK and acts as category_id or FK for the Product class: </p>
  
  <pre><code>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&lt;Product&gt; 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;
  }
  
  }
  </code></pre>
  
  <p>Here is my ProductController : </p>
  
  <pre><code>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&lt;Product&gt; products=productService.getAllProducts();
      //productlist - logical view name [productlist.jsp]
      //products - model attribute [use this attribute in jsp]
      //products - List&lt;Product&gt; 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&lt;Category&gt; 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&lt;Category&gt; 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";
      }
  
  }
  </code></pre>
  
  <p>Shouldn't the AUTO generated strategy automatically generate id for product class as we add more products via the frontend dynamically?(Instead of encountering a null value for another entry of product) I'm new to hibernate and any help would be appreciated!</p>
  
  <p><a href="https://i.stack.imgur.com/wzgC7.png" rel="nofollow noreferrer">Here is my product table at backend H2</a></p>