Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6712587
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 26, 20262026-05-26T08:16:38+00:00 2026-05-26T08:16:38+00:00

we’re developing an application using JSF 2.0 (primefaces) and Hibernate 3.6.1 We’re following the

  • 0

we’re developing an application using JSF 2.0 (primefaces) and Hibernate 3.6.1
We’re following the approch of letting the higher level of the application be agnostic about the DAL framework…. that means that we don’t use the session-per-request approach, but we configured Hibernate to handle the sessione on a per-thread basis.
We’ve implemented a class whose role is to handle an “atomic operation”, taking care of open the session and the transaction when they don’t exixt already, and to simply hook other db operation to the existing transaction, to make them part of the main operation, witount letting them know if they’re executing independently or as part of a bigger operation.
This is the code for our OperationManager:

public class OperationManager implements IOperationManager {

    Transaction tx = null;
    boolean isInternalTransaction = false;

    /* (non-Javadoc)
     * @see alekso.npe.dal.IOperationManager#beginOperation()
     */
    @Override
    public Session beginOperation(){            
        Session session = SessionFactoryUtil.getInstance().getCurrentSession();
        if (session.getTransaction().isActive()) {
            isInternalTransaction = false;  
            tx = session.getTransaction();
        }
        else {
            isInternalTransaction = true;
            tx = session.beginTransaction();
        }
        return session;
    }

    /* (non-Javadoc)
     * @see alekso.npe.dal.IOperationManager#commitOperation()
     */
    @Override
    public void commitOperation(){
        if (isInternalTransaction)
            tx.commit();
    }

    /* (non-Javadoc)
     * @see alekso.npe.dal.IOperationManager#rollbackOperation()
     */
    @Override
    public void rollbackOperation(){
        if (isInternalTransaction)
            tx.rollback();
    }
}

The SessionFactoryUtil class, is the “classic” factory util for hibernate, suggested everywhere… we picked up this implementation:

public class SessionFactoryUtil {

final static Logger log = Logger.getLogger(SessionFactoryUtil.class);

/** The single instance of hibernate SessionFactory */
private static org.hibernate.SessionFactory sessionFactory;

/**
 * disable contructor to guaranty a single instance
 */
private SessionFactoryUtil() {
}

static {
    // Annotation and XML
    // sessionFactory = new
    // AnnotationConfiguration().configure().buildSessionFactory();
    // XML only
    try {
        sessionFactory = new Configuration().configure().buildSessionFactory();
    } catch (Exception e) {
        log.error("Errore nella creazione del session factory", e);
        System.out.println("Errore nella creazione del session factory");
    }

}

public static SessionFactory getInstance() {
    try{
        return sessionFactory;
    } catch (Exception ex)
    {
        log.error("errore nella creazione della session di hibernate", ex);
        return null;
    }
}

/**
 * Opens a session and will not bind it to a session context
 * 
 * @return the session
 */
public Session openSession() {
    return sessionFactory.openSession();
}

/**
 * Returns a session from the session context. If there is no session in the
 * context it opens a session, stores it in the context and returns it. This
 * factory is intended to be used with a hibernate.cfg.xml including the
 * following property <property
 * name="current_session_context_class">thread</property> This would return
 * the current open session or if this does not exist, will create a new
 * session
 * 
 * @return the session
 */
public Session getCurrentSession() {
    return sessionFactory.getCurrentSession();
}

/**
 * closes the session factory
 */
public static void close() {
    if (sessionFactory != null)
        sessionFactory.close();
    sessionFactory = null;

}
}

Now, how do we use the operation manager?
Simply, whoever is intended to be responsable for an atomic operation on the db, call the method on OperationManager.

public class BL1{
    public void highMethod() {      
        IOperationManager om = new OperationManager();
        BL2 bl2 = new BL2();
        BL3 bl3 = new BL3();
        try {           
            om.beginOperation();            

            bl2.midMethod();
            bl3.midMethod();

            om.commitOperation();           
        } catch (Exception ex) {
            omrollbackOperation();      
        }       
    }
}

public class BL2{
    public void midMethod() {       
        IOperationManager om = new OperationManager();
        DAL1 dal1 = new DAL1();
        DAL2 dal2 = new DAL2();
        try {           
            om.beginOperation();            

            dal1.lowMethod1();
            dal2.lowMethod1();

            om.commitOperation();           
        } catch (Exception ex) {
            omrollbackOperation();      
        }       
    }
}

public class BL3{
    public void midMethod() {       
        IOperationManager om = new OperationManager();
        DAL1 dal1 = new DAL1();
        DAL2 dal2 = new DAL2();
        try {           
            om.beginOperation();            

            dal1.lowMethod2();
            dal2.lowMethod2();

            om.commitOperation();           
        } catch (Exception ex) {
            omrollbackOperation();      
        }       
    }
}

public class DAL1{
    public void lowMethod1() {      
        IOperationManager om = new OperationManager();
        Session session = nullM
        try {                                   
            session = om.beginOperation();

            // do some work on session
            session.saveOrUpdate(...);
            session.load(..);
            session.somethingElse(....);

            om.commitOperation();           
        } catch (Exception ex) {
            omrollbackOperation();      
        }       
    }
    public void lowMethod2() {      
        IOperationManager om = new OperationManager();
        Session session = nullM
        try {                                   
            session = om.beginOperation();

            // do some work on session
            session.saveOrUpdate(...);
            session.load(..);
            session.somethingElse(....);

            om.commitOperation();           
        } catch (Exception ex) {
            omrollbackOperation();      
        }       
    }
}

public class DAL2{
    public void lowMethod1() {      
        IOperationManager om = new OperationManager();
        Session session = nullM
        try {                                   
            session = om.beginOperation();

            // do some work on session
            session.saveOrUpdate(...);
            session.load(..);
            session.somethingElse(....);

            om.commitOperation();           
        } catch (Exception ex) {
            omrollbackOperation();      
        }       
    }
    public void lowMethod2() {      
        IOperationManager om = new OperationManager();
        Session session = nullM
        try {                                   
            session = om.beginOperation();

            // do some work on session
            session.saveOrUpdate(...);
            session.load(..);
            session.somethingElse(....);

            om.commitOperation();           
        } catch (Exception ex) {
            omrollbackOperation();      
        }       
    }
}    
}

Doing so, if I call the BL1.highMethod, everyting below (al the method colled from inside) will be under the transiction it started: the om.beginOperation() on the method called, simply returns the session started by BL1.highMethod, and the om.commitOperation or om.rollBackOperation of the method called, simply do nothing at all, leaving at the om instance created in BL1.highMethod the responsability to commit/rollback and close the session.
But if we call directly BL2.midMethod, the responsability for managing session and transaction, will be its own. The same happen if we call directly DAL1.lowMethod1.
The pattern is: if I (as a method) didn’t called beginOperation, everything I use to get my job done, will handle the session/transaction on its own; if I beginOperation, it’ll be my responsability to manage session/transiction.
I hope I made it clear.

Now, it seemed to me to be a very smart approach… until something goes wrong.
What is going wrong, it’s really hard to tell.
Simply the application start to act weird: sometimes the application create a lock on the db, during an update (the database talk about a locking row, but looking at the sequence of sql statement flushed to the db, it has no sense); sometimes there’s no lock, and no error logged, but the application seems to read “old data”… like if the operation we did couple of seconds ago, is not there… and it appear to be there just after 30 seconds (or 10, or 60… it depends). I mean, very strage behaviour. We only see some error on the log, whne we hit the rowlock on the db, that brings to a long live transaction, otherwise nothing seems wrong. To make things more complicated, the same exact sequence of user operation on the application (on the same record, byy the same user, etc…) sometimes work, sometimes not.
And this behaviour happen from when we refactor the code introducing the pattern I showed above, using the OperationManager class.

Anyone out there has an idea of what we did wrong, why this pattern is not working as desired?
I apologies for the lenght of the question posted…

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-26T08:16:38+00:00Added an answer on May 26, 2026 at 8:16 am

    Actually I solved my issues typing the question above!
    In the last part of code, the class and method that called the OperationManager, I declared and istantiate the OperationManager object right inside the method. This way the flag isInternalTransaction is bound to the method itself.
    In my real code, in a class I declared OperationManager at class level: this means that calls to different methods of the same class instance, broke the pattern, because the isInternalTransaction falg where modified from outside the owner method!
    So that’s the only bug I had: the use I made of the service I created for the pattern, not the pattern itself.
    Now it works great, even without Spring.

    That’s good for me, not just for the reason that I don’t have to learn spring just beacause of this, but also because I prefer to dig deeper in a problem/pattern, and understand why and how it works… not just taking something that works, and consider it magic 😉

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm using v2.0 of ClassTextile.php, with the following call: $testimonial_text = $textile->TextileRestricted($_POST['testimonial']); ... and
link Im having trouble converting the html entites into html characters, (&# 8217;) i
That's pretty much it. I'm using Nokogiri to scrape a web page what has
I'm new to using the Perl treebuilder module for HTML parsing and can't figure
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
We're building an app, our first using Rails 3, and we're having to build
I'm making a simple page using Google Maps API 3. My first. One marker
We are using XSLT to translate a RIXML file to XML. Our RIXML contains
I ran into a problem. Wrote the following code snippet: teksti = teksti.Trim() teksti
I have thousands of HTML files to process using Groovy/Java and I need to

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.