Announcement Announcement Module
Collapse
No announcement yet.
org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update

    Hi,

    I am using struts,spring and hibernate.

    I have a users table where the administrator can add the new users in it through the application.

    If the user is already present in the db then i want to display the user a message that "user already exist" else save the user in the db.

    However whenever i am trying to add the duplicate entry i get the following exception:

    Hibernate: select nextval ('users_id_seq')
    Hibernate: insert into users (username, password, id) values (?, ?, ?)
    WARN org.hibernate.util.JDBCExceptionReporter::logExcep tions() - SQL Error: 0, SQLState: null
    ERROR org.hibernate.util.JDBCExceptionReporter::logExcep tions() - Batch entry 0 insert into users (username, password, id) values ('steve', 'sdf', 3) was aborted.
    ERROR org.hibernate.event.def.AbstractFlushingEventListe ner:erformExecutions() - Could not synchronize database state with session
    org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update
    at org.hibernate.exception.SQLStateConverter.handledN onSpecificException(SQLStateConverter.java:103)
    at org.hibernate.exception.SQLStateConverter.convert( SQLStateConverter.java:91)
    at org.hibernate.exception.JDBCExceptionHelper.conver t(JDBCExceptionHelper.java:43)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(Ab stractBatcher.java:249)
    at org.hibernate.engine.ActionQueue.executeActions(Ac tionQueue.java:235)
    at org.hibernate.engine.ActionQueue.executeActions(Ac tionQueue.java:139)
    at org.hibernate.event.def.AbstractFlushingEventListe ner.performExecutions(AbstractFlushingEventListene r.java:298)
    at org.hibernate.event.def.DefaultFlushEventListener. onFlush(DefaultFlushEventListener.java:27)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.j ava:1000)
    at org.springframework.orm.hibernate3.HibernateAccess or.flushIfNecessary(HibernateAccessor.java:394)
    at org.springframework.orm.hibernate3.HibernateTempla te.execute(HibernateTemplate.java:366)
    at org.springframework.orm.hibernate3.HibernateTempla te.save(HibernateTemplate.java:612)
    at com.comp.model.dao.hibernateImpl.LoginDaoHibernate Impl.saveUser(LoginDaoHibernateImpl.java:58)
    at com.comp.model.serviceImpl.LoginServiceImpl.saveUs er(LoginServiceImpl.java:43)
    at com.comp.view.UserAddAction.execute(UserAddAction. java:57)
    at org.apache.struts.action.RequestProcessor.processA ctionPerform(RequestProcessor.java:419)
    at org.apache.struts.action.RequestProcessor.process( RequestProcessor.java:224)
    at org.apache.struts.action.ActionServlet.process(Act ionServlet.java:1196)
    at org.apache.struts.action.ActionServlet.doPost(Acti onServlet.java:432)
    at javax.servlet.http.HttpServlet.service(HttpServlet .java:709)
    at javax.servlet.http.HttpServlet.service(HttpServlet .java:802)
    at org.apache.catalina.core.ApplicationFilterChain.in ternalDoFilter(ApplicationFilterChain.java:252)
    at

    My query:

    1) Why i dont get proper error message such as "Duplicate entry or some violation error"

    2) Also i am not able to catch the exception.

    Code as follows:
    User.hbm.xml
    -------------
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
    <hibernate-mapping package="com.comp.model.businessobject">
        <class name="User" table="users">
    
            <id name="id" column="id" type="java.lang.Long">
                <generator class="sequence">
                    <param name="sequence">users_id_seq</param>
    
                </generator>
            </id>
            <property name="username" column="username" not-null="true" />
            <property name="password" column="password" not-null="true" />
        </class>
    </hibernate-mapping>
    applicationContext.xml
    ---------------------
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
    
    <!--
        - Root application context for the Countries application.
        - Web-specific beans are defined in "countries-servlet.xml".
    -->
    <beans>
    
        <!--
            - The message source for this context, loaded from localized "messages_xx" files
            - in the classpath, i.e. "/WEB-INF/classes/messages.properties" or
            - "/WEB-INF/classes/messages_fr.properties".
            -
            - "getMessage" calls to this context will use this source.
            - Child contexts can have their own message sources, inheriting all messages from this
            - source, being able to define new messages and override ones defined in this source.
            -
            - We have no need for application messages in this tiny application, so this
            - definition will simply be used by the next level (countries-servlet.xml).
        -->
        <bean id="messageSource"
            class="org.springframework.context.support.ResourceBundleMessageSource">
            <property name="basename" value="messages" />
        </bean>
    
    
        <!-- ========================= Start of PERSISTENCE DEFINITIONS ========================= -->
    
        <!-- DataSource Definition -->
        <bean id="dataSource"
            class="org.apache.commons.dbcp.BasicDataSource"
            destroy-method="close">
            <property name="driverClassName">
                <value>org.postgresql.Driver</value>
            </property>
            <property name="url">
                <value>jdbc:postgresql://127.0.0.1:5432/somedb</value>
    
            </property>
            <property name="username">
                <value>postgres</value>
            </property>
            <property name="password">
                <value>postgres</value>
            </property>
        </bean>
    
        <!-- Hibernate SessionFactory Definition -->
        <bean id="sessionFactory"
            class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
            <property name="mappingResources">
                <list>
                    <value>
                        com/comp/model/businessobject/User.hbm.xml
                    </value>
                </list>
            </property>
    
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.dialect">
                        org.hibernate.dialect.PostgreSQLDialect
                    </prop>
                    <prop key="hibernate.show_sql">true</prop>
                    <!--<prop key="hibernate.cglib.use_reflection_optimizer">true</prop>-->
                    <!--<prop key="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</prop>-->
                </props>
            </property>
    
            <property name="dataSource">
                <ref bean="dataSource" />
            </property>
        </bean>
    
        <!-- Spring Data Access Exception Translator Defintion -->
        <bean id="jdbcExceptionTranslator"
            class="org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator">
            <property name="dataSource">
                <ref bean="dataSource" />
            </property>
        </bean>
    
        <!-- Hibernate Template Defintion -->
        <bean id="hibernateTemplate"
            class="org.springframework.orm.hibernate3.HibernateTemplate">
            <property name="sessionFactory">
                <ref bean="sessionFactory" />
            </property>
            <property name="jdbcExceptionTranslator">
                <ref bean="jdbcExceptionTranslator" />
            </property>
        </bean>
    
    
        <!-- Login DAO object: Hibernate implementation -->
        <bean id="loginDao"
            class="com.comp.model.dao.hibernateImpl.LoginDaoHibernateImpl">
            <property name="hibernateTemplate">
                <ref bean="hibernateTemplate" />
            </property>
        </bean>
    
        <!-- ========================= Start of SERVICE DEFINITIONS ========================= -->
    
        <!--  User Service Defintion -->
        <bean id="loginService"
            class="com.comp.model.serviceImpl.LoginServiceImpl">
            <property name="loginDao">
                <ref bean="loginDao" />
            </property>
        </bean>
    
    
        <!-- Hibernate Transaction Manager Definition -->
        <bean id="transactionManager"
            class="org.springframework.orm.hibernate3.HibernateTransactionManager">
            <property name="sessionFactory">
                <ref local="sessionFactory" />
            </property>
        </bean>
    
    </beans>
    DAO class:
    ------------
    Code:
    public User saveUser(User user, HttpServletRequest request)
                throws UserAlreadyExistClass {
    
            User receiveduser = null;
            try {
                getHibernateTemplate().save(user);
            } catch (Exception x) {
                throw new UserAlreadyExistClass("User already exist");
    
            }
    
            return receiveduser;
        }
    I also tried adding getHibernateTemplate().flush(); after save still it didnt worked.

    Thanks
    Last edited by enjoystar; Mar 14th, 2007, 01:29 AM.

  • #2
    It really helps to put the code in [ code] [ /code] tags, it's sooo much easier to read! If you flush straight after the save, what actually happens? Is it possible this exception isn't actually generation until the transaction commits.

    Comment


    • #3
      It was my first post so didnt knew how to put code.
      From next time onwards I will take care to put the code in code tags
      thanks for letting me know that .

      After using flush still it throws the same exception.

      I updated the postgres driver to the latest one and now I get the exception message
      in details(ie:duplicate key violates unique constraint) as follows:

      Exception
      Code:
      hibernate: insert into users (username, password, id) values (?, ?, ?)
      WARN  org.hibernate.util.JDBCExceptionReporter::logExceptions() - SQL Error: 0, SQLState: null
       ERROR org.hibernate.util.JDBCExceptionReporter::logExceptions() - Batch entry 0 insert into users (username, password, id) values (steve, sdfasf, 8) was aborted.  Call getNextException to see the cause.
       WARN  org.hibernate.util.JDBCExceptionReporter::logExceptions() - SQL Error: 0, SQLState: 23505
       ERROR org.hibernate.util.JDBCExceptionReporter::logExceptions() - ERROR: duplicate key violates unique constraint "users_username_key"
       ERROR org.hibernate.event.def.AbstractFlushingEventListener::performExecutions() - Could not synchronize database state with session
       org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
      	at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
      	at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
      	at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:249)
      	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235)
      	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:139)
      	at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
      	at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
      	at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
      	at org.springframework.orm.hibernate3.HibernateAccessor.flushIfNecessary(HibernateAccessor.java:387)
      	at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:368)
      	at org.springframework.orm.hibernate3.HibernateTemplate.save(HibernateTemplate.java:627)
      	at com.comp.model.dao.hibernateImpl.LoginDaoHibernateImpl.saveUser(LoginDaoHibernateImpl.java:59)
      However still I am not able to catch the exception in my catch clause and the exception is thrown on the webpage


      Karl: I didnt get what you mean by the following statement:
      Is it possible this exception isn't actually generation until the transaction commits.

      Comment


      • #4
        I don't see why you wouldn't be able to catch the exception. What I was trying to understand was were the exception was actually generated. As it's in the Dao I can't see why you can't catch it!

        Comment


        • #5
          I am also confused why the control doesnt go in the catch clause.
          i am using spring 2 and hibernate3 and struts 1.2.8. Do you think are the able versions are not compatible with each others?

          Can you try the above code i have pasted?
          As i am still stuck with it for last 2 days and not able to find the way out of it.

          Comment


          • #6
            Is it possible to see the full stacktrace?

            Comment


            • #7
              Here is the complete stack strace.
              Code:
               INFO  com.comp.view.UserAddAction::execute() - *** execute() ***
               INFO  com.comp.view.UserAddAction::execute() - Button Clicked = Add
               INFO  com.comp.model.dao.hibernateImpl.LoginDaoHibernateImpl::saveUser() - *** saveUser
               Hibernate: select nextval ('users_id_seq')
              Hibernate: insert into users (username, password, id) values (?, ?, ?)
              WARN  org.hibernate.util.JDBCExceptionReporter::logExceptions() - SQL Error: 0, SQLState: null
               ERROR org.hibernate.util.JDBCExceptionReporter::logExceptions() - Batch entry 0 insert into users (username, password, id) values (steve, sdfasd, 2) was aborted.  Call getNextException to see the cause.
               WARN  org.hibernate.util.JDBCExceptionReporter::logExceptions() - SQL Error: 0, SQLState: 23505
               ERROR org.hibernate.util.JDBCExceptionReporter::logExceptions() - ERROR: duplicate key violates unique constraint "users_username_key"
               ERROR org.hibernate.event.def.AbstractFlushingEventListener::performExecutions() - Could not synchronize database state with session
               org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
              	at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
              	at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
              	at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:249)
              	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235)
              	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:139)
              	at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
              	at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
              	at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
              	at org.springframework.orm.hibernate3.HibernateAccessor.flushIfNecessary(HibernateAccessor.java:387)
              	at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:368)
              	at org.springframework.orm.hibernate3.HibernateTemplate.saveOrUpdate(HibernateTemplate.java:681)
              	at com.comp.model.dao.hibernateImpl.LoginDaoHibernateImpl.saveUser(LoginDaoHibernateImpl.java:70)
              	at com.comp.model.serviceImpl.LoginServiceImpl.saveUser(LoginServiceImpl.java:41)
              	at com.comp.view.UserAddAction.execute(UserAddAction.java:57)
              	at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:419)
              	at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:224)
              	at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)
              	at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
              	at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
              	at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
              	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
              	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
              	at org.displaytag.filter.ResponseOverrideFilter.doFilter(ResponseOverrideFilter.java:125)
              	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
              	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
              	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
              	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
              	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
              	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
              	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
              	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
              	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:868)
              	at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:663)
              	at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
              	at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
              	at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
              	at java.lang.Thread.run(Unknown Source)
              Caused by: java.sql.BatchUpdateException: Batch entry 0 insert into users (username, password, id) values (steve, sdfasd, 2) was aborted.  Call getNextException to see the cause.
              	at org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handleError(AbstractJdbc2Statement.java:2530)
              	at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1317)
              	at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:350)
              	at org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch(AbstractJdbc2Statement.java:2592)
              	at org.apache.commons.dbcp.DelegatingPreparedStatement.executeBatch(DelegatingPreparedStatement.java:231)
              	at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
              	at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:242)
              	... 34 more
              INFO  com.comp.model.dao.hibernateImpl.LoginDaoHibernateImpl::saveUser() - ***********************Catch the error
               INFO  com.comp.view.UserAddAction::execute() - back

              Also I have created the table using the following SQL commands:
              CREATE TABLE users
              (
              id serial NOT NULL,
              username varchar(20) NOT NULL,
              "password" varchar(20) NOT NULL,
              CONSTRAINT users_pkey PRIMARY KEY (id),
              CONSTRAINT users_username_key UNIQUE (username)
              )
              WITHOUT OIDS;
              ALTER TABLE users OWNER TO postgres;
              Last edited by enjoystar; Mar 15th, 2007, 06:11 AM.

              Comment


              • #8
                Ok, we aren't getting anywhere. Could you write a simple test case and post that, the code and the configuration. I'll take a look.

                Comment


                • #9
                  Here are some related links for this thread:
                  http://www.oreillynet.com/onjava/blo...tabaserel.html

                  Solution with getJpaTemplate().flush();

                  But not clear how to implement this using EntityMenager in my Book repository (called BookService), so below is complete JUnit test example that could help:


                  Code:
                  import java.sql.SQLException;
                  
                  import javax.persistence.EntityManager;
                  import javax.persistence.PersistenceContext;
                  
                  import org.apache.log4j.Logger;
                  import org.junit.Test;
                  import org.junit.runner.RunWith;
                  import org.springframework.beans.factory.annotation.Autowired;
                  import org.springframework.test.annotation.Rollback;
                  import org.springframework.test.context.ContextConfiguration;
                  import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
                  import org.springframework.transaction.annotation.Transactional;
                  
                  @RunWith(SpringJUnit4ClassRunner.class)
                  @ContextConfiguration(locations = { "/META-INF/spring/applicationContext.xml" })
                  public class MyTest {
                  
                  	private Logger log = Logger.getLogger(MyTest.class);
                  
                  	@Autowired
                  	private BookService bookService;
                  	
                  	@PersistenceContext
                  	private EntityManager em;
                  
                  	@Test
                  	@Rollback(false)
                  	@Transactional
                  	public void testMethod() throws Exception{
                  		try {
                  			bookService.save("09876543210987654321098");
                  			em.flush();
                  		} catch (Throwable e) {
                  			Throwable ex = e;
                  			while (ex.getCause() != null) {
                  				log.error(ex.getMessage(), ex);
                  				ex = ex.getCause();
                  			}
                  			if (ex instanceof java.sql.BatchUpdateException){
                  				SQLException nextException = ((java.sql.BatchUpdateException) ex).getNextException();
                  				log.error(nextException.getMessage(), nextException);
                  			}
                  		}
                  	}
                  }
                  Error was data truncation, which I figured out earlier but want to find way to log correct error in log file:

                  org.postgresql.util.PSQLException: ERROR: value too long for type character varying(20)

                  Here is part of output log:

                  Code:
                  Hibernate: 
                      select
                          nextval ('book_seq')
                  Hibernate: 
                      /* insert org.dali.persistence.Book
                          */ insert 
                          into
                              public.book
                              (name, id) 
                          values
                              (?, ?)
                  2011-09-03 19:38:00,693 [main] ERROR org.dali.persistence.MyTest - org.hibernate.exception.DataException: Could not execute JDBC batch update
                  javax.persistence.PersistenceException: org.hibernate.exception.DataException: Could not execute JDBC batch update
                  	at ...
                  ...
                  Caused by: java.sql.BatchUpdateException: Batch entry 0 /* insert org.dali.persistence.Book */ insert into public.book (name, id) values ('09876543210987654321098', '30092') was aborted.  Call getNextException to see the cause.
                  	at ...
                  ...
                  2011-09-03 19:38:00,701 [main] ERROR org.dali.persistence.MyTest - Could not execute JDBC batch update
                  org.hibernate.exception.DataException: Could not execute JDBC batch update
                  	at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:102)
                  	at ...
                  ...
                  Caused by: java.sql.BatchUpdateException: Batch entry 0 /* insert org.dali.persistence.Book */ insert into public.book (name, id) values ('09876543210987654321098', '30092') was aborted.  Call getNextException to see the cause.
                  	at org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handleError(AbstractJdbc2Statement.java:2586)
                  	at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1811)
                  	at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:407)
                  	at ...
                  ...
                  2011-09-03 19:38:00,703 [main] ERROR org.dali.persistence.MyTest - ERROR: value too long for type character varying(20)
                  org.postgresql.util.PSQLException: ERROR: value too long for type character varying(20)
                  	at ...
                  ...

                  Hope this will help someone

                  David

                  Comment

                  Working...
                  X