views:

78

answers:

1

I'm developing a web app with Spring and Hibernate and I was so obsessed by making he application thread safe and being able to support heavy load that based on my boss recommendation I end up writing my own session and a session container to implement a session per request pattern. Plus I have a lot of DAOs and me not willing to write the same save method for all the DAOs I copy paste this Hibernate GenericDAO (I can't tell it's the same thing because at the time hibernate wasn't owned by jboss) and do the plumbing stuff, and under pressure, all become quickly complicated and on production, the is StaleObjectException and duplicated data right, and i have the feeling that it's time to review what I've done, simplify it and make it more robust for large data handling. One thing you should know is that one request involves many DAO's.

There is quartz running for some updates in the database.

As much as I want to tune everything for the better I lack time to do the necessary research plus Hibernate is kind of huge (learning).

So this is it, I'll like to borrow your experience and ask for few question to know what direction to take.

Question 1 : is Hibernate generated uuid safe enough for threading environment and avoiding StaleObjectException?

Question 2 what are best strategy to use hibernate getCurrentSession in threadSafe scenario (I've read about threadlocal stuff but didn't get too much understanding so didn't do it)

Question 3 : will HIbernateTemplate do for the simplest solution approach?

Question 4 : what will be your choice if you were to implement a connection pool and tuning requirement for production server?

Please do no hesitate to point me to blogs or resources online , all that I need is a approach that works for my scenario. your approach if you were to do this.

Thanks for reading this, everybody's idea is welcomed...

+5  A: 

I'm developing a web app with Spring and Hibernate and I was so obsessed by making he application thread safe and being able to support heavy load that based on my boss recommendation I end up writing my own session and a session container to implement a session per request pattern.

You should just drop all this code and use Spring/Hibernate APIs instead: less bugs, less maintenance.

I copy paste this Hibernate GenericDAO (I can't tell it's the same thing because at the time hibernate wasn't owned by jboss) and do the plumbing stuff, and under pressure, all become quickly complicated (...)

You can use a GenericDao and inject the required stuff with Spring.

Question 1: is Hibernate generated uuid safe enough for threading environment and avoiding StaleObjectException?

To strictly answer your question, here is what Reference Guide writes about the uuid generator:

5.1.4.1. Generator

...

  • uuid

    uses a 128-bit UUID algorithm to generate identifiers of type string that are unique within a network (the IP address is used). The UUID is encoded as a string of 32 hexadecimal digits in length.

So I consider it as safe. But I think your StaleObjectException are unrelated (it's another problem).

Question 2: what are best strategy to use hibernate getCurrentSession in threadSafe scenario (I've read about threadlocal stuff but didn't get too much understanding so didn't do it)

The best strategy is to just use it, sessionFactory.getCurrentSession() will always give you a Session scoped to the current database transaction aka a "contextual session". Again, quoting the Reference Documentation:

2.5. Contextual sessions

Most applications using Hibernate need some form of "contextual" session, where a given session is in effect throughout the scope of a given context. However, across applications the definition of what constitutes a context is typically different; different contexts define different scopes to the notion of current. Applications using Hibernate prior to version 3.0 tended to utilize either home-grown ThreadLocal-based contextual sessions, helper classes such as HibernateUtil, or utilized third-party frameworks, such as Spring or Pico, which provided proxy/interception-based contextual sessions.

(...)

However, as of version 3.1, the processing behind SessionFactory.getCurrentSession() is now pluggable. To that end, a new extension interface, org.hibernate.context.CurrentSessionContext, and a new configuration parameter, hibernate.current_session_context_class, have been added to allow pluggability of the scope and context of defining current sessions.

See the Javadocs for the org.hibernate.context.CurrentSessionContext interface for a detailed discussion of its contract. It defines a single method, currentSession(), by which the implementation is responsible for tracking the current contextual session. Out-of-the-box, Hibernate comes with three implementations of this interface:

  • org.hibernate.context.JTASessionContext: current sessions are tracked and scoped by a JTA transaction. The processing here is exactly the same as in the older JTA-only approach. See the Javadocs for details.
  • org.hibernate.context.ThreadLocalSessionContext: current sessions are tracked by thread of execution. See the Javadocs for details.
  • org.hibernate.context.ManagedSessionContext: current sessions are tracked by thread of execution. However, you are responsible to bind and unbind a Session instance with static methods on this class: it does not open, flush, or close a Session.

(...)

There is no need to implement your own ThreadLocal-based solution nowadays, don't do that.

Question 3 : will HIbernateTemplate do for the simplest solution approach?

Well, the HibernateTemplate is not deprecated but it is not recommended anymore and I prefer to implement template-less DAOs:

public class ProductDaoImpl implements ProductDao {

    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    public Collection loadProductsByCategory(String category) {
        return this.sessionFactory.getCurrentSession()
                .createQuery("from test.Product product where product.category=?")
                .setParameter(0, category)
                .list();
    }
}

Where the SessionFactory is injected by Spring. I suggest to read So should you still use Spring's HibernateTemplate and/or JpaTemplate?? for complete background and also the whole section 13.3. Hibernate in the Spring documentation on ORM Data Access.

Question 4 : what will be your choice if you were to implement a connection pool and tuning requirement for production server?

Hmm... What? I would never implement my connection pool but use the one from my application server. Maybe you should clarify this question.

Update: In production, I wouldn't use Hibernate built-in connection pool but configure Hibernate to use an application server provided JNDI datasource (and thus the application server connection pool). From the documentation:

3.3. JDBC connections

...

Here is an example hibernate.properties file for an application server provided JNDI datasource:

hibernate.connection.datasource = java:/comp/env/jdbc/test
hibernate.transaction.factory_class = \
    org.hibernate.transaction.JTATransactionFactory
hibernate.transaction.manager_lookup_class = \
    org.hibernate.transaction.JBossTransactionManagerLookup
hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect

JDBC connections obtained from a JNDI datasource will automatically participate in the container-managed transactions of the application server.

Pascal Thivent
Thanks Pascal for all the effort put into this comment.I'ts almost like an article.I'm reading the resources and use best what is all out there.thanks again!!
black sensei
@blacksensei: You're welcome. I tried to put interesting links in there. Let me know if you need more clarification.
Pascal Thivent
Hi about the question 4 i was asking about connection management from hibernate.on the web here and there you find tutorial on hibernate with connection pooling.so i was asking whether it is the best practice in production server.pooling like c3p0, proxool and apache commons jdbc... thanks again for your precious help
black sensei