Results 1 to 9 of 9

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

  1. #1
    Join Date
    Mar 2007
    Posts
    8

    Default 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 at 01:29 AM.

  2. #2
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    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.

  3. #3
    Join Date
    Mar 2007
    Posts
    8

    Default

    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.

  4. #4
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    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!

  5. #5
    Join Date
    Mar 2007
    Posts
    8

    Default

    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.

  6. #6
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    Is it possible to see the full stacktrace?

  7. #7
    Join Date
    Mar 2007
    Posts
    8

    Default

    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 at 06:11 AM.

  8. #8
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    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.

  9. #9
    Join Date
    Sep 2011
    Posts
    1

    Default

    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

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •