sass
sass

Reputation: 309

JSF 2.0 and hibernate adding new objects to a postgresql database

I'm writing a JSF 2.0 application with Hibernate and Postgresql database. My problem is quite poor understanding on how to handle session with Hibernate when inserting data into more than one table at a time. I have a method savePerson. The method is called as many times as there are addresses submitted by a user but the object Person is only created once. The method savePerson then calls the method addAddress. The code looks like this:

public Person savePerson(Person p, String address) {

        Transaction tx = null;
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();

        if (p == null) {
             = new Person();

            try {
                tx = session.beginTransaction();
                session.save(p);
                tx.commit();
            } catch (RuntimeException e) {
                if (tx != null && tx.isActive()) {
                    try {

                        tx.rollback();
                    } catch (HibernateException e1) {
                    }

                    throw e;
                }
            }
        }

        int id = p.getId();
        addAddress(4, id, address);

        return p;
    }

And the method addAddress:

public void addAddress(int table_id, int row_id, String address) {

        Transaction tx = null;
        session = HibernateUtil.getSessionFactory().openSession();
        Address a = new Address(table_id, row_id, address);

        try {
            tx = session.beginTransaction();
            session.save(a);
            tx.commit();
        } catch (RuntimeException e) {
            System.out.println("first try");

            if (tx != null && tx.isActive()) {
                System.out.println("first try if");
                try {
                    System.out.println("first try if try");

                    tx.rollback();
                } catch (HibernateException e1) {

                }
                // throw again the first exception
                throw e;
            }
            throw e;
        }

But I get the following error:

org.hibernate.TransactionException: Transaction not successfully started

So what is the proper way of opening and closing session when inserting the data into more than one table at a time?

Best Regards, sass.

Upvotes: 1

Views: 1103

Answers (2)

Pascal Thivent
Pascal Thivent

Reputation: 570595

A TransactionException indicates that a transaction could not be begun, committed or rolled back. But providing the full stacktrace would probably helpful to fully understand the problem.

That being said, while you can create multiple (serial) Transaction from a single Session, there is IMO a major flaw in your design. If you need to insert both the Person and the Address, you should very likely do it in a single unit of work. With your current approach, adding an Address can fail and leave a freshly inserted Person in an inconsistent state.

So what is the proper way of opening and closing session when inserting the data into more than one table at a time?

Do it in a single transaction.

And if you want to remove the transaction management from your methods, you should consider using the Open Session In View pattern, as suggested by BalusC. Unless you want finer grained transaction control of course.

Resources

Upvotes: 1

BalusC
BalusC

Reputation: 1109570

A common practice would be to create a Filter which opens the Hibernate session before processing the request/response and commits and closes the session after processing the request/response. Finally map this Filter on <servlet-name> of FacesServlet. This is called Open Session In View or Open Session Per Request.

Spring provides such a filter out of the box, the OpenSessionInViewFilter, which is useful for the case that you're already using Spring or are considering to use it. If you don't (want to) do Spring, you can find here another concrete kickoff examples which you could just copypaste and finetune/expand.

Another practices are listed in this MyFaces FAQ (although MyFaces 1.2 targeted, this applies as good on Mojarra 1.x and 2.x).

Upvotes: 1

Related Questions