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.
A
TransactionExceptionindicates 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)
Transactionfrom a singleSession, there is IMO a major flaw in your design. If you need to insert both thePersonand theAddress, you should very likely do it in a single unit of work. With your current approach, adding anAddresscan fail and leave a freshly insertedPersonin an inconsistent state.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