[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
Re: [eclipselink-dev] questions while running JPA JUnit tests
|
Hi Andrei,
Thank you for your suggestion.
Unfortunately it did not work. When it does the INSERT on the temporary
table, the driver returns an error saying the table is in use by another
user.
From what I understand from the code (only had a brief look), the
effect of the local setting over global is that the table is dropped
instead of the data in it being deleted at the end of its use.
What I think I need is a setting to have the creation of the temporary
table be executed in a separate transaction (even separate connection as
a transaction on the current connection might already have started?)
from the execution of the INSERT above and following DELETE (or DROP,
which again would need to be done in a separate transaction).
I can see
ExpressionQueryManager#buildStatementsForUpdateAllForTempTables and
#buildStatementsForDeleteAllForTempTables methods build the statements
and pass a mode to them. If we could check this mode when the statements
are executed we can obtain a separate connection and enclose calls with
mode SQLModifyAllStatementForTempTable.CLEANUP_TEMP_TABLE in
begin/commit transaction calls.
What do you think?
Thanks,
Dies
Andrei Ilitchev wrote:
Try specifying temporary tables as local rather than global.
----- Original Message ----- From: "Dies Koper" <diesk@xxxxxxxxxxxxxxxxxxx>
To: "Dev mailing list for Eclipse Persistence Services"
<eclipselink-dev@xxxxxxxxxxx>
Sent: Thursday, September 24, 2009 8:21 AM
Subject: Re: [eclipselink-dev] questions while running JPA JUnit tests
Hi Tom,
I finally got this test suite to stop hanging and locking.
I ended up putting the transaction begin/commit statements here:
- In SchemaManager#createObject/dropObject(in the if
(shouldWriteToDatabase()) block).
- In SequenceDefinition#createOnDatabase I put "checkIfExist(session)"
in a try-finally block, with a rollback in the finally clause,
followed by a beginTransaction. This was necessary because in the case
of sequence objects (not sequence tables), checkIfExist did a SELECT
nextval and createOnDatabase did a CREATE SEQUENCE, so I needed to
separate the DML from the DDL.
With that I still had problems with the global temporary table. A
number of tests in this suite rely on updateAll and deleteAll.
With global temporary tables disabled
(shouldAlwaysUseTempStorageForModifyAll() returns false), I get no
hangs/locks but I get an SQLException (see last week's e-mail "same
table in from clauses of query and subquery").
With global temporary tables implemented, creation of the table goes
fine, but the following INSERT fails because the table is "locked".
I'm not sure if I can (or should) put this table's create statement in
a transaction, I suppose this whole query could already be running in
a transaction.
Another issue with Symfoware's temporary tables is that the table
space name for the table must be specified at creation time. It does
not default to the table space that creation of normal tables default
to. So we'd need a way for the user to define this table space.
In what cases are updateAll/deleteAll required exactly? Are they
related to JPA 2.0 functions? Are they required for JPA 1.0
functionality too?
As I see no clean solution I wonder what the impact is of making this
a limitation for this platform for now.
With the global table disabled, I pass 176 tests (72%) of
EntityManagerJUnitTestSuite. The 45 errors are all due to the problem
above. Good news I suppose.
I'll try some more suites tomorrow.
If I no longer run into locking issues, what will the final solution
look like? Can I add a method createObjectsInTransactions() to the DB
platforms, defaulting to false of course, true for Symfoware, that
begins/commits/rolls back transactions in the locations I described
above?
Thanks,
Dies
Dies Koper wrote:
Hi Tom,
I am trying to enclose DDL calls with transactions. Inside
schemaManager.createSequences() there are mixed DDL and DML (select
and inserts on the sequence table/object), so just I'm moving the
transaction calls deeper into the call stack.
The locking error I get now is from the SELECT statement on table
CMP3_ENTITYB_SEQ in the following call in SchemaManager#createObject.
databaseObjectDefinition.createOnDatabase(getSession());
I did put a getSession().beginTransaction(); before this call, so I'm
not sure yet what the problem is. I'll investigate a bit more and let
you know.
Thanks,
Dies
The idea is that we would add calls that begin and commit
transactions around table creation calls.
Lets see if it works before we design the final solution:
- Find the
org.eclipse.persistence.tools.schemaframework.TableCreator.replaceTables(session,
schemaManager) method
- Add transactional boundaries
public void
replaceTables(org.eclipse.persistence.sessions.DatabaseSession
session, SchemaManager schemaManager) {
session.beginTransaction();
replaceTablesAndConstraints(schemaManager, session);
schemaManager.createSequences();
session.commitTransaction();
}
- Run
org.eclipse.persistence.testing.tests.jpa.advanced.EntityManagerJUnitTestSuite
- Ensure your logging is at FINER or FINEST and look for log
messages like the following around the code that does DDL generation:
[EL Finer]:
ServerSession(16925102)--Connection(14004497)--Thread(Thread[main,5,main])--begin
transaction
<a whole lot of DDL here>
[EL Finer]:
ServerSession(16925102)--Connection(14004497)--Thread(Thread[main,5,main])--commit
transaction
- make sure there are no DDL statements outside of those boundries
- see if it makes any difference to your tests
Assuming we cannot solve the issue with transactions, the
problem really comes down to the session that is passed into the
constructors for SchemaManager. That is the session used to
execute DDL. Changing the API is likely the cleanest way to do
that, but I am a bit concerned about the number of files we will
have to change to achieve that. I'll have to give some thought to
a solution that combines a reasonable number of changes to test
files with logical API.
I am still not sure what is causing the hangs and lock errors, so
if you could first suggest some temporal changes to a subset of
tests that I can apply and try to see if that solves all issues,
that would be great.
We may be able to add a temporary solution by creating some kind
of static session that we use for DDL generation and using that
session instead of the ones passed into the SchemaManager
constructor. Then we can try logging it in and out as DDL calls
are made. I am a bit concerned about that effect that will have
on how long the tests take to run, but I'll try to do some
experimentation.
How do sessions relate to the JDBC connections?
I am hoping that we can find a DB transaction related solution since
a solution like that will fit much better into the EclipseLink
schema creation architecture.
In JPA, an EntityManager holds a construct called a ClientSession.
A ClientSession communicates with a construct called a ServerSession
to make us of connections (an EntityManagerFactory holds the
ServerSession). A ServerSession holds a number of pools of
connections. (for reading, for writing, for sequences)