toplink session and UnitOfWork synchronization problem
430305Sep 30 2004 — edited Sep 30 2004
Dear forum readers,
I am not sure i fully understand the way how toplink deals with caching. To me it seems, that i got some pretty scary results, which i am not sure how to interpret and to work around them.
The following code snippet is part of a unit test:
>>>>>>>>>>>> snip >>>>>>>>>>>>>>>
1 public void test2() {
2
3 UnitOfWork uow = (UnitOfWork) SessionManager.getSessionManager().getSession().getUnitOfWork();
4 Justitiabele justitiabele = findJustitiabele("findById", Justitiabele.class, new Long(551));
5 ((JustitiabeleIdentiteit) justitiabele.getJustitiabeleIdentiteiten().iterator().next()).setMeisjesnaam("Kettner10");
6 Justitiabele tmp = (Justitiabele) uow.registerObject(justitiabele);
7 ((JustitiabeleIdentiteit) tmp.getJustitiabeleIdentiteiten().iterator().next()).setMeisjesnaam("Kettner10");
8 uow.commitAndResume();
9 }
10
11 public Justitiabele findJustitiabele(String queryName, Class objectClass, Object param) {
12 SessionWrapper toplinkSessionWrapper = getSession();
13 toplinkSessionWrapper.getClientSession().executeQuery(queryName, objectClass, param);
14 }
>>>>>>>>>>>>>>>> snip <<<<<<<<<<<<<<<<
I am querying a particular object (line 4). Then i make some changes to that object (line 5). Cause the object is not registered in the UnitOfWork these changes shouldn't be persisted. So far so good. To achieve persistency i now register the object, and i make the same modifications to the toplink clone, expecting them after the commit to be persisted in the database.
Contrary to my expectations, the changes were not persisted!!!
Deleting line 5 (the modifications, before registering the object), leads to the desired result.
Somehow the queried object seems to be a direct reference to the (client-) session cache. So when registering the object in the UnitOfWork, the (already modified) backupclone is copied from the session cache to the UnitOfWork. If the same changes are done to the working clone,there are no differences between backup- and working clone and no changes are made in the database.
It gets even better: I tried to query the object again (before line 6) (even with a different UnitOfWork) before modifying it, in order to retrieve the original state of the object, but again i only was able to find the modified object.
If the queried object indeed is a reference to some cache, i cannot understand, why that cache is not read only!!!
Am i doing something wrong ?
Is there a way to work around this problem?
What are the consequences for transaction handling ? What about Isolation, when clients can see each others changes in a kind of writeable shared session???
I try to work around that problem by registering every object, that is queried from the database in the UnitOfWork right after it was queried. This seems to me the only solution, though this is contrary to what the toplink developers guide says, namely, that only objects which are modified should be registered, due to performance reasons.
I would be grateful to any help in understanding and working around this problem.
Martin
PS: Here's the log i got by running the test.:
STDOUT >>>>>>>>>>>>>>>>>>>>>>>>>>>>
C:\devtools\jdev\905\jdk\bin\javaw.exe -ojvm -classpath C:\ToplinkDemo\ToplinkDomein\classes;C:\ToplinkDemo\ToplinkDomein\classes\META-INF\ToplinkDomein;C:\devtools\jdev\905\toplink\jlib\source.jar;C:\devtools\jdev\905\lib\xmlparserv2.jar;C:\devtools\jdev\905\lib\xmlcomp.jar;C:\devtools\jdev\905\jdbc\lib\classes12.jar;C:\devtools\jdev\905\jdbc\lib\nls_charset12.jar;C:\devtools\jdev\905\toplink\jlib\toplink.jar org.dji.br.bl.domein.TestMain
ServerSession(91)--Connection(92)--TopLink, version: OracleAS TopLink - 10g (9.0.4) (Build 031126)
ServerSession(91)--Connection(92)--connecting session: djisession
ServerSession(91)--Connection(92)--connecting(DatabaseLogin(
platform=>Oracle9Platform
user name=> "dji"
datasource URL=> "jdbc:oracle:thin:@S-ORACLE01:1521:djipoc"
))
ServerSession(91)--Connection(92)--Connected: jdbc:oracle:thin:@S-ORACLE01:1521:djipoc
User: DJI
Database: Oracle Version: Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 - Production
Driver: Oracle JDBC driver Version: 9.0.1.5.0
ServerSession(91)--Connection(101)--TopLink, version: OracleAS TopLink - 10g (9.0.4) (Build 031126)
ServerSession(91)--Connection(101)--connecting session: djisession
ServerSession(91)--Connection(101)--connecting(DatabaseLogin(
platform=>Oracle9Platform
user name=> "dji"
datasource URL=> "jdbc:oracle:thin:@S-ORACLE01:1521:djipoc"
))
ServerSession(91)--Connection(101)--Connected: jdbc:oracle:thin:@S-ORACLE01:1521:djipoc
User: DJI
Database: Oracle Version: Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 - Production
Driver: Oracle JDBC driver Version: 9.0.1.5.0
ServerSession(91)--Connection(103)--TopLink, version: OracleAS TopLink - 10g (9.0.4) (Build 031126)
ServerSession(91)--Connection(103)--connecting session: djisession
ServerSession(91)--Connection(103)--connecting(DatabaseLogin(
platform=>Oracle9Platform
user name=> "dji"
datasource URL=> "jdbc:oracle:thin:@S-ORACLE01:1521:djipoc"
))
ServerSession(91)--Connection(103)--Connected: jdbc:oracle:thin:@S-ORACLE01:1521:djipoc
User: DJI
Database: Oracle Version: Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 - Production
Driver: Oracle JDBC driver Version: 9.0.1.5.0
ServerSession(91)--Connection(105)--TopLink, version: OracleAS TopLink - 10g (9.0.4) (Build 031126)
ServerSession(91)--Connection(105)--connecting session: djisession
ServerSession(91)--Connection(105)--connecting(DatabaseLogin(
platform=>Oracle9Platform
user name=> "dji"
datasource URL=> "jdbc:oracle:thin:@S-ORACLE01:1521:djipoc"
))
ServerSession(91)--Connection(105)--Connected: jdbc:oracle:thin:@S-ORACLE01:1521:djipoc
User: DJI
Database: Oracle Version: Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 - Production
Driver: Oracle JDBC driver Version: 9.0.1.5.0
ServerSession(91)--Connection(107)--TopLink, version: OracleAS TopLink - 10g (9.0.4) (Build 031126)
ServerSession(91)--Connection(107)--connecting session: djisession
ServerSession(91)--Connection(107)--connecting(DatabaseLogin(
platform=>Oracle9Platform
user name=> "dji"
datasource URL=> "jdbc:oracle:thin:@S-ORACLE01:1521:djipoc"
))
ServerSession(91)--Connection(107)--Connected: jdbc:oracle:thin:@S-ORACLE01:1521:djipoc
User: DJI
Database: Oracle Version: Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 - Production
Driver: Oracle JDBC driver Version: 9.0.1.5.0
ServerSession(91)--Connection(109)--TopLink, version: OracleAS TopLink - 10g (9.0.4) (Build 031126)
ServerSession(91)--Connection(109)--connecting session: djisession
ServerSession(91)--Connection(109)--connecting(DatabaseLogin(
platform=>Oracle9Platform
user name=> "dji"
datasource URL=> "jdbc:oracle:thin:@S-ORACLE01:1521:djipoc"
))
ServerSession(91)--Connection(109)--Connected: jdbc:oracle:thin:@S-ORACLE01:1521:djipoc
User: DJI
Database: Oracle Version: Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 - Production
Driver: Oracle JDBC driver Version: 9.0.1.5.0
ServerSession(91)--Connection(111)--TopLink, version: OracleAS TopLink - 10g (9.0.4) (Build 031126)
ServerSession(91)--Connection(111)--connecting session: djisession
ServerSession(91)--Connection(111)--connecting(DatabaseLogin(
platform=>Oracle9Platform
user name=> "dji"
datasource URL=> "jdbc:oracle:thin:@S-ORACLE01:1521:djipoc"
))
ServerSession(91)--Connection(111)--Connected: jdbc:oracle:thin:@S-ORACLE01:1521:djipoc
User: DJI
Database: Oracle Version: Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 - Production
Driver: Oracle JDBC driver Version: 9.0.1.5.0
ServerSession(91)--sequencing connected, state is ForcedToUseWriteAccessor_State
ServerSession(91)--client acquired
ClientSession(114)--acquire unit of work: 113
ClientSession(114)--Execute query ReadObjectQuery(org.dji.br.bl.domein.justitiabele.Justitiabele)
ServerSession(91)--Connection(101)--SELECT DJI_NUMMER FROM DJI.JUSTITIABELEN WHERE (DJI_NUMMER = 551)
ServerSession(91)--Execute query ReadAllQuery(org.dji.br.bl.domein.justitiabele.JustitiabeleIdentiteit)
ServerSession(91)--Connection(92)--SELECT INDICATIE_NONAMER, ACHTERNAAM, BRN_CODE, MEISJESNAAM, ID, ROEPNAAM, GEBOORTEPLAATS_BUITENLAND, TITEL_BUITENLAND, VOORNAAM, VOORLETTERS, JBE_DJI_NUMMER, DATUM_INGANG, DATUM_EINDE FROM DJI.JUSTITIABELEIDENTITEITEN WHERE (JBE_DJI_NUMMER = 551)
ServerSession(91)--Execute query ReadObjectQuery(org.dji.br.bl.domein.justitiabele.Justitiabele)
UnitOfWork(113)--Register the object org.dji.br.bl.domein.justitiabele.Justitiabele@82
UnitOfWork(113)--Register the existing object org.dji.br.bl.domein.justitiabele.JustitiabeleIdentiteit@84
UnitOfWork(113)--Register the existing object org.dji.br.bl.domein.justitiabele.Justitiabele@82
UnitOfWork(113)--begin unit of work commit
ClientSession(114)--Connection(103)--begin transaction
UnitOfWork(113)--Execute query WriteObjectQuery(org.dji.br.bl.domein.justitiabele.Justitiabele@83)
UnitOfWork(113)--Execute query WriteObjectQuery(org.dji.br.bl.domein.justitiabele.JustitiabeleIdentiteit@85)
ClientSession(114)--Connection(103)--commit transaction
UnitOfWork(113)--end unit of work commit
UnitOfWork(113)--resume unit of work
Process exited with exit code 0.