W
wish
I'm currently struggling with Hibernate 3.1.1 to which our app is being
migrated from 3.0.5. There is a major problem with transactions which seem
to be working not exactly as they were. I'm moving the system from MySQL
4.1.x to 5.0.x and J/Connector from 3.1.0 to 3.1.13 also. That's a lot of
unknown factors but perhaps someone had similar problem? Here's a piece of
code I'm trying to run:
/*
Start a time consuming procedure which with God's help produces a sales
report
*/
Transaction t = null;
Iterator it = null;
Object [] row = null;
try {
t = session.beginTransaction();
/*
Create an initial query to get a list of the shops, that the data
has to be gathered for.
This is a pure select, nothing to update, but the query should be in
transaction as
it is said in the manual... The query is executed by the .iterate()
metod which gives an
Iterator to the resultSet (as I presume...), and does not download
the 200 MB List of
Hibernate classes instantly into memory, like the .list().iterator()
method.
*/
it = query.iterate();
t.commit();
} catch (Exception e) {
if (t != null) t.rollback();
throw e;
}
/*
Now iterate through results and perform queries for each object with
some .sleep() for each one to
prevent the machine from melting....
*/
while (it.hasNext()) {
/*
Point 1. The row is a tuple of objects. This is the place where
Hibernate performs
again query for each object that should be fetched in the main
query, and created from the
original JDBC ResultSet without any other queries.
Does the first .commit() disconnects the objects from the ResultSet
somehow and Hibernate feels urgent need to refresh them..???.
This doesn't happen while there's .list().iterator() method used.
*/
row = (Object []) it.next();
try {
/*
Point 2. Here another transaction is being created, as
apparently all "units-of-work" should be
inside it. For each chosen shop there are some calculations
being made, though there
are again no updates or inserts.
*/
t = session.beginTransaction();
TObject1 A = row[0];
/*
Here get some properties of A, make calculations per row and
append the row to the report (StringBuffer with CSV data)
...
..
*/
/*
Point 3. A commit per iteration.
*/
t.commit();
session.flush(); System.gc(); // .... and some other pathetic
attempts to clear the memory...
} catch (Exception e) {
if (t != null) t.rollback();
throw e;
}
}
So... there is a problem. It seems, that at Point 2. Hibernate creates
transaction for each iteration... or not... and does not bother to tell me,
if there is a problem at this point. This causes an exception at Point 3.
"Transaction not successfully started".
My questions are:
- what was changed in 3.1.1 that could affect the behaviour of
transactions?.
- are there some ways of getting the tuple of objects in row of ResultSet
without fetching them again or loading the entire result into memory?
- how can i control if there was no success creating new transaction and
what possible settings/drivers/events in the Hibernate or in JDBC could
affect this behaviour?
- is there a way to perform a nested transaction in Hibernate?
- how to effectively clear the memory from unused Hibernate objects after
each iteration?
I'll be grateful for some advice or a piece of doc to read.
Thanks,
wish
migrated from 3.0.5. There is a major problem with transactions which seem
to be working not exactly as they were. I'm moving the system from MySQL
4.1.x to 5.0.x and J/Connector from 3.1.0 to 3.1.13 also. That's a lot of
unknown factors but perhaps someone had similar problem? Here's a piece of
code I'm trying to run:
/*
Start a time consuming procedure which with God's help produces a sales
report
*/
Transaction t = null;
Iterator it = null;
Object [] row = null;
try {
t = session.beginTransaction();
/*
Create an initial query to get a list of the shops, that the data
has to be gathered for.
This is a pure select, nothing to update, but the query should be in
transaction as
it is said in the manual... The query is executed by the .iterate()
metod which gives an
Iterator to the resultSet (as I presume...), and does not download
the 200 MB List of
Hibernate classes instantly into memory, like the .list().iterator()
method.
*/
it = query.iterate();
t.commit();
} catch (Exception e) {
if (t != null) t.rollback();
throw e;
}
/*
Now iterate through results and perform queries for each object with
some .sleep() for each one to
prevent the machine from melting....
*/
while (it.hasNext()) {
/*
Point 1. The row is a tuple of objects. This is the place where
Hibernate performs
again query for each object that should be fetched in the main
query, and created from the
original JDBC ResultSet without any other queries.
Does the first .commit() disconnects the objects from the ResultSet
somehow and Hibernate feels urgent need to refresh them..???.
This doesn't happen while there's .list().iterator() method used.
*/
row = (Object []) it.next();
try {
/*
Point 2. Here another transaction is being created, as
apparently all "units-of-work" should be
inside it. For each chosen shop there are some calculations
being made, though there
are again no updates or inserts.
*/
t = session.beginTransaction();
TObject1 A = row[0];
/*
Here get some properties of A, make calculations per row and
append the row to the report (StringBuffer with CSV data)
...
..
*/
/*
Point 3. A commit per iteration.
*/
t.commit();
session.flush(); System.gc(); // .... and some other pathetic
attempts to clear the memory...
} catch (Exception e) {
if (t != null) t.rollback();
throw e;
}
}
So... there is a problem. It seems, that at Point 2. Hibernate creates
transaction for each iteration... or not... and does not bother to tell me,
if there is a problem at this point. This causes an exception at Point 3.
"Transaction not successfully started".
My questions are:
- what was changed in 3.1.1 that could affect the behaviour of
transactions?.
- are there some ways of getting the tuple of objects in row of ResultSet
without fetching them again or loading the entire result into memory?
- how can i control if there was no success creating new transaction and
what possible settings/drivers/events in the Hibernate or in JDBC could
affect this behaviour?
- is there a way to perform a nested transaction in Hibernate?
- how to effectively clear the memory from unused Hibernate objects after
each iteration?
I'll be grateful for some advice or a piece of doc to read.
Thanks,
wish