-->
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: ConstraintViolationException working in 2 or more tx
PostPosted: Thu Apr 29, 2010 4:31 pm 
Newbie

Joined: Fri Sep 18, 2009 12:45 pm
Posts: 2
Hi
When I am saving a large set of objects in a long transaction, I am getting primary key constraintviolation. I am saving a NetworkElement which has children and grandchildren..
The dbobjects are defined in an hierarchy.NetworkElement(has),Shelf(has),Pack(has), DSLPort. All objects have their own oracle sequence defined. NetworkElement also has association with other
objects, in a one-to-one or one-to-many relations.
I parse a registry from the NetworkElement and save all the children and grandchildren objects in the database, includin the NE and its associated objects, inside a long spring platformtransaction.

When I am parsing 2 NetworkElements simultaneously, with lot of data in it, I endup with ConstraintViolationException, in any of the child objects or the associated objects with the Network Element. The transaction
fails and a rollback happens.
Each NetworkElement do not have common children, so a DSLPort in one NE is independent of another DSLPort in another NE. But the 2 independent transactions running simultaneously complain about
ConstraintViolation on any of the objects, say DSLPort here.

For instance I mostly get ConstraintViolation on DSLPortDBObj, each NE has a large set of ports. The primary key is handled by Hibernate, it retrieves the sequence id before saving.

Code:
@MappedSuperclass
public abstract class ManagedIdCMDBObject extends EMSDBObject{
   protected Integer id;
   protected Long version;
   
    @Id
    @GeneratedValue(generator="SEQ_GEN")   
   public Integer getId() {
      return id;
   }
....

Code:
@Table(name = "DSLPORT")
@Entity
@GenericGenerator(name = "SEQ_GEN", strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator",
      parameters = {
      @Parameter(name = "sequence_name", value = "DSLPORT_SEQ"),
      @Parameter(name = "initial_value", value = "1"),
      @Parameter(name = "increment_size", value = "1") })
public class DSLPortDBObj extends ManagedIdCMDBObject implements Serializable {
    private PackDBObj pack;
    @ManyToOne
    @JoinColumn(name="fk_dsl_pack")
    @ForeignKey(name="fk_dsl_pack")
    @Index(name="INDEX_DSL_PACK")
   public PackDBObj getPack() {
      return pack;
   }

Code:
@Table(name = "PACK")
@GenericGenerator(name = "SEQ_GEN", strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator",
      parameters = {
      @Parameter(name = "sequence_name", value = "PACK_SEQ"),
      @Parameter(name = "initial_value", value = "1"),
      @Parameter(name = "increment_size", value = "1") })
public class PackDBObj extends ManagedIdCMDBObject implements Serializable {
        private List<DSLPortDBObj> dslPorts = new ArrayList<DSLPortDBObj>();
   @OneToMany( mappedBy = "pack")         
   public List<DSLPortDBObj> getDslPorts() {
      return dslPorts;
   }


called by EMSDBServiceImpl
Code:
public class GenericDaoImpl<T, ID extends Serializable> extends HibernateDaoSupport
    implements GenericDaoInterface<T, ID>{
public T persist(final T entity) throws DataAccessException {
       getHibernateTemplate().persist(entity);       
       return entity;
    }


called by CMDTOServiceImpl
Code:
@Transactional(propagation=Propagation.SUPPORTS)
public class EMSDBServiceImpl implements EMSDBServiceInterface{
    protected GenericDaoImpl genericDao = null;
    public EMSDBObject add(EEUFdn parentFdn, EMSDBObject dbObj) throws   
    DBException {
       //set links to parent object, pack and then save
       EMSDBObject o = (EMSDBObject) dbService.getGenericDao().persist(emsObjectDBObj);
    }


called by discoveryutils
Code:
@Transactional(propagation = Propagation.REQUIRED)
public class CMDTOServiceImpl implements CMDTOServiceInterface {
//inject the dbservice
public CMObject addCMObject(EEUFdn parentFdn, CMObject cmObject) throws DTOException {
try {
--convert cmObject(DTO Object) to dbobject using dozer library.
dbService.add(parentFdn, (ManagedIdCMDBObject)dbObj);
..
} catch (Exception e) {
            throw new DTOException(BaseExceptionEnum.DTO_ADD_FAILED,
                  cmObject.getFdn().toString(),  e);
        }





Code:
public class CMDiscoveryUtils {
    public static void writeRegistry2DB(..) {
         PlatformTransactionManager platformTransactionManager =   CMDiscoveryMgr.getInstance().getTransactionManager();
        TransactionStatus status = platformTransactionManager.getTransaction(new DefaultTransactionDefinition());
        try {
            NEDBObj cluster = getClusterFromDB(neId);
            ..
            for (int i = 0; i < numShelves; i++) {
                ..save shelf
                for each pack {
                    --save multiple DSLPorts in a loop.
                    DSLPortDBObj dsl = new DSLPortDBObj();
                    dsl.setAid(portAid);         
                    CMDiscoveryMgr.getInstance().getDBService(). add(pack.getFdn(), dsl);
                }
                [color=#FF0000]...query shelf object causes flush of DSLPorts and mostly causes constraintviolation on the primary key[/color]
            }
        } catch (Exception ex) {
            platformTransactionManager.rollback(status);
            EntLogger.severe(CMDiscoveryUtils.class, ex.getMessage(), ex);
            throw ex;
        }
        platformTransactionManager.commit(status);
}

The platformtransaction in CMDiscoveryUtils starts the transaction and the DTOService continues the transaction. The CMDTOService has transaction defined at the class level(annotation based).

If 2 different transactions are saving the multiple DSLPorts, the transactions seem to be retrieving distinct primary keys from DSLPort_Seq from Oracle. But at the time of flush caused by query, ahead of the commit, one of the DSLPort persist throws an ConstraintViolationException on the primary key id. The log does not seem to indicate the same id being used.
I can only reproduce this when I have a large set of DSLPorts but not otherwise. Please advice what is going wrong.


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.