jchitel
jchitel

Reputation: 3169

Hibernate - Session closed after getting query

I have a central class for all Hibernate logic (which I didn't write most of). Let's call it HibCentral.

My code uses this class to create a query from a SQL string:

public class HibCentral {

    ...some hibernate setup and other methods...

    @Transactional
    public Query createSQLQuery(final String sql) {
        return getCurrentSession().createSQLQuery(sql);
    }
}

getCurrentSession() just calls sessionFactory.getCurrentSession().

My class (let's call it MyClass) is called by a high level service (Service). It gets a SQL string, calls this method to get a query, populates its parameters, and sends it back to the service. The service then calls the query using query.list().

public class MyClass {
    public Query getQuery(Args args) {
        Query q = hibCentral.createSQLQuery(getSQLString());
        setParameters(q);
        return q;
    }
}

public class Service {
    public void doIt() {
        Query q = myClass.getQuery(args);
        // some logic
        List list = q.list();
    }
}

But wait, the session is closed.

I tried to move the list() call to the Hibernate-logic class as well:

public class HibCentral {

    ....other methods....

    @Transactional
    public List list(final Query query) {
        return query.list();
    }
}

but this produced the same "the session is closed" error.

What do I do to make this work?

Upvotes: 0

Views: 2270

Answers (2)

Sachin Thapa
Sachin Thapa

Reputation: 3709

When you use @Transactional it applies to a method unless you specify @Transactional(propagation=Propagation.REQUIRED).

As soon as method call finishes transaction is closed, hence the session. You should create query get the list and return in same method.

@Transactional
    public List createSQLQuery(final String sql) {
        Query query = getCurrentSession().createSQLQuery(sql);
        return q.list();
    }

Cheers !!

Upvotes: 0

Luiggi Mendoza
Luiggi Mendoza

Reputation: 85779

The problem is that only the methods in HibCentral class are transactional, which means that the database connection opens and closes for the execution of those methods only. After that, the connection will be closed and any interaction with an Hibernate element like Query outside those methods won't have a valid connection and you will get those errors.

Solution: move the @Transactional annotation to a higher level. This should be usually at service layer. If your classes in the service layer interact between each other, then move the @Transactional to a higher level in order to avoid opening and closing many connections.

Upvotes: 1

Related Questions