-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 
Author Message
 Post subject: Batch insert or update in multiple threads
PostPosted: Mon Oct 30, 2006 4:41 am 
Newbie

Joined: Mon Oct 30, 2006 4:14 am
Posts: 1
I build application which import data into database. I do this job in multiple threads. After few record Hibernate throws exception
Quote:
unique constraint (XXX.UQ_TESTA) violated

or
Quote:
unique constraint (XXX.PK_TESTB) violated
.
I don't know why.

Thanks,

Martin

SQL to build test DB:
Code:
CREATE TABLE TESTA
(
  A   NUMBER(4)                                 NOT NULL,
  AB  NUMBER(4)                                 NOT NULL,
  C   VARCHAR2(10 BYTE)
)
TABLESPACE XXX
PCTUSED    0
PCTFREE    10
INITRANS   1
MAXTRANS   255
STORAGE    (
            INITIAL          64K
            MINEXTENTS       1
            MAXEXTENTS       2147483645
            PCTINCREASE      0
            BUFFER_POOL      DEFAULT
           )
LOGGING
NOCACHE
NOPARALLEL
NOMONITORING;


ALTER TABLE TESTA ADD (
  CONSTRAINT PK_TESTA
PRIMARY KEY
(A));

ALTER TABLE TESTA ADD (
  CONSTRAINT UQ_TESTA
UNIQUE (C));


ALTER TABLE TESTA ADD (
  CONSTRAINT FK_AB
FOREIGN KEY (AB)
REFERENCES TESTB (B));



CREATE TABLE TESTB
(
  B  NUMBER(4)                                  NOT NULL
)
TABLESPACE XXX
PCTUSED    0
PCTFREE    10
INITRANS   1
MAXTRANS   255
STORAGE    (
            INITIAL          64K
            MINEXTENTS       1
            MAXEXTENTS       2147483645
            PCTINCREASE      0
            BUFFER_POOL      DEFAULT
           )
LOGGING
NOCACHE
NOPARALLEL
NOMONITORING;


ALTER TABLE TESTB ADD (
  CONSTRAINT PK_TESTB
PRIMARY KEY
(B));


Mapping file testa:
Code:
<hibernate-mapping package="hr.test">
   <class
      name="Testa"
      table="TESTA"
   >
      <meta attribute="sync-DAO">false</meta>
      <id
         name="Id"
         type="integer"
         column="A"
      >
         <generator class="increment"/>
      </id>
      <property name="c" column="C" type="string" length="10"/>
      
      <many-to-one
         name="ab"
         column="AB"
         class="Testb"
         not-null="true"
         cascade="save-update"
      >          
      </many-to-one>

   </class>   
</hibernate-mapping>


Mapping file testb:
Code:
<hibernate-mapping package="hr.test">
   <class
      name="Testb"
      table="TESTB"
   >      <meta attribute="sync-DAO">false</meta>
      <id
         name="Id"
         type="integer"
         column="B"
      >
         <generator class="assigned"/>
      </id>

   
      <set name="As" inverse="true">
         <key column="B" not-null="true"/>
         <one-to-many class="Testa"/>
      </set>
   </class>
</hibernate-mapping>


Hiberante config file:
Code:
<hibernate-configuration>
   <session-factory>
      <!-- local connection properties -->
      <property name="hibernate.connection.url">
         jdbc:oracle:thin:@test:1521:orcl
      </property>
      <property name="hibernate.connection.driver_class">
         oracle.jdbc.driver.OracleDriver
      </property>
      <property name="hibernate.connection.username">test</property>
      <property name="hibernate.connection.password">test</property>
      <property name="hibernate.connection.pool_size">20</property>
      <property name="current_session_context_class">thread</property>
      <property name="hibernate.jdbc.batch_size">20</property>
      <property name="hibernate.cache.use_second_level_cache">false</property>
      <!-- dialect for Oracle (any version) -->
      <property name="dialect">
         org.hibernate.dialect.OracleDialect
      </property>
      <property name="hibernate.show_sql">false</property>
      <property name="hibernate.transaction.factory_class">
         org.hibernate.transaction.JDBCTransactionFactory
      </property>
      <mapping resource="Testa.hbm.xml" />
      <mapping resource="Testb.hbm.xml" />
   </session-factory>
</hibernate-configuration>


Test code (test.java):
Code:
package hr.logos.test;

import hr.util.ACSHibernateUtil;

public class Test {

   /**
    *Randomly select some record
    */
   public static Testa getTest() {
      Testa r = new Testa();
      r.setC(""+Math.round((Math.random()*100)));
      r.setAb(new Testb((int)Math.round((Math.random()*100))));
      return r;
   }
   
   /**
    * @param args
    */
   public static void main(String[] args) {
      ThreadGroup threadGroup = new ThreadGroup("test");
      ACSHibernateUtil.initialize();

      for(int i=0; i < 50000; i++) {
         while(threadGroup.activeCount() > 32){
            try {
               Thread.sleep(10);
            }
            catch(Exception e) {}
         }
         
         Thread t = new Thread(threadGroup, new TestaRunnable(i));
         if(t != null) t.start();
      }
      
      while(threadGroup.activeCount() > 0){
         try {
            Thread.sleep(10);
         }
         catch(Exception e) {}
      }
      ACSHibernateUtil.closeSession();
   }

}

Test code (TestaRunnable.java):
Code:
package hr.test;

import hr.util.ACSHibernateUtil;

import java.util.List;

import org.apache.log4j.Logger;


public class TestaRunnable implements Runnable {
   static Logger logger = Logger.getLogger(TestaRunnable.class);
   
   private int id=0;
   
   public TestaRunnable(int id) {
      this.id = id;
   }
   
   private Testa getTesta(String cond) {
      List result = null;
      result = ACSHibernateUtil.getSession().createQuery(
            "from Testa where c=?")
            .setString(0,cond).list();
      
      if ((result == null ? 0 : result.size()) == 0)
         return null;
      return (Testa) result.get(0);
   }

   private void insertTesta(Testa t) {
      ACSHibernateUtil.getSession().save(t);
   }

   private void updateTesta(Testa t) {
      ACSHibernateUtil.getSession().update(t);
   }

   public void run() {
      Testa kFile = null;
      try {
         kFile = Test.getTest();
      }
      catch (Exception e) {
         e.printStackTrace();
         return;
      }

      Testa kBase = null;
      int Id = 0;

       try {
          ACSHibernateUtil.beginTransaction();
         kBase = getTesta(kFile.getC());

         // if not exists in DB then insert
         if (kBase == null) {
            insertTesta(kFile);
         }
         //else update record
         else {
            ACSHibernateUtil.evict(kBase);
            Id = kBase.getId();
            kFile.setId(Id);
            kFile.setAb(kBase.getAb());
            updateTesta(kFile);
         }
         ACSHibernateUtil.commitTransaction();
      }
      catch (Exception e) {
         e.printStackTrace();
         ACSHibernateUtil.rollbackTransaction();
      }
   }
}

Test code (ACSHibernateUtil.java):
Code:
package hr.util;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class ACSHibernateUtil {

   private static final SessionFactory sessionFactory;

   private static final ThreadLocal threadSession = new ThreadLocal();
   private static final ThreadLocal threadTransaction = new ThreadLocal();

   static {
      try {
         Configuration cfg = new Configuration().configure("hibernate.cfg.xml");
            sessionFactory = cfg.buildSessionFactory();
      } catch (Throwable ex) {
         throw new ExceptionInInitializerError(ex);
      }
   }
   
   public static void initialize(){
      //do nothing
   }

   public static Session getSession()  {
      Session s = (Session) threadSession.get();
      try {
         if (s == null) {
            s = sessionFactory.openSession();
            threadSession.set(s);
         }
      } catch (HibernateException ex) {
      }
      return s;
   }

   public static void closeSession(){
      try {
         Session s = (Session) threadSession.get();
         threadSession.set(null);
         if (s != null && s.isOpen())
            s.close();
      } catch (HibernateException ex) {
      }
   }

   public static void beginTransaction() {
      Transaction tx = (Transaction) threadTransaction.get();
      try {
         if (tx == null) {
            tx = getSession().beginTransaction();
            threadTransaction.set(tx);
         }
      } catch (HibernateException ex) {
      }
   }

   public static void commitTransaction()throws HibernateException {
      Transaction tx = (Transaction) threadTransaction.get();
      try {
         threadTransaction.set(null);
         if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack())
            tx.commit();
      } catch (HibernateException ex) {
         rollbackTransaction();
         throw ex;
      }
   }

   public static void rollbackTransaction(){
      Transaction tx = (Transaction) threadTransaction.get();
      try {
         threadTransaction.set(null);
         if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack()) {
            tx.rollback();
         }
      } catch (HibernateException ex) {
   
      } finally {
         closeSession();
      }
   }

}


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.