Kodo 2.5 Joins
Manual says:
"Added the com.solarmetric.kodo.impl.jdbc.UseSQL92Joins configuration
property. Set this property to 'true' to use SQL 92-style joins in queries,
including left outer joins where appropriate. You can also set this property
on an individual query instance; see the
com.solarmetric.kodo.impl.jdbc.query.JDBCQuery class Javadoc for details."
Could you please clarify the "outer join issue". Do I have any control over
choosing inner or outer? I would not want to use outer if I can use inner
(non null oreign key enforced reference) - much faster
Patrick,
Any chance to make it work for collections too? Most of my staff is in
collections. I do not use queries very much. We want nice object model and
queries are really secondary. Unfortunately very often fetching this
collections is slow because (well fetching the collection itself is fine) of
lazy reference resolution on collection members.
In case joining is possible for collections we would need to be able to
enable/disable joining on PM level and also be able to configure in metadata
via fetch groups and explicit instructions which references I want joined.
"Patrick Linskey" <[email protected]> wrote in message
news:b5e9hr$ptu$[email protected]..
Alex Roytman wrote:
And also what controls joining?
- When is it used and when it is not? How to control itThe use of outer joins is determined by the nature of queries that you
execute. There aren't currently any user-available hints for outer join
control. In internal builds in which we know more information about
referential integrity constraints, we'll be able to do some more clever
decision-making.
- Can custom fetch groups and PM level fetch group definitions control
join
vs. lazy reference traversal?Custom fetch groups + fetch group config can be used to control whether or
not tables might be joined into initial queries, yes. But it does not
control the nature of whether we use outer or inner joins.
- Is it used on single objects? on queries? on collections reading?Queries.
Any plans to add fetch group config on query level too?Not currently, but probably someday. Currently, the closest you can get is
to change the PM, execute the query, and change back, which is less than
ideal if you're using the PM in multiple threads, but that's what you've
got for now.
-Patrick
Similar Messages
-
ClassCastException in KodoHelper
Hi Folks
I received a ClassCastException when invoking KodoHelper.getPersistenceManagerFactory(File). The exception implies to me that Kodo is casting its PersistenceManagerFactoryImpl class to some incompatible type.
Here is the contents of kodo.properties:
javax.jdo.PersistenceManagerFactoryClass=kodo.jdo.PersistenceManagerFactoryImpl
kodo.ConnectionURL=jdbc:hsqldb:file://c:/projects/temporal/db/temporaldb
kodo.ConnectionDriverName=org.hsqldb.jdbcDriver
kodo.ConnectionUserName=sa
kodo.ConnectionPassword=
kodo.MetaDataFactory=jdo
kodo.Log=DefaultLevel=WARN, Runtime=TRACE, Tool=TRACE
Here is the log output:
C:\dev\jdk1.5.0_07\bin\java -Didea.launcher.port=7542 "-Didea.launcher.bin.path=C:\Program Files\JetBrains\IntelliJ IDEA 5.1\bin" -Dfile.encoding=windows-1252 -classpath "C:\dev\jdk1.5.0_07\jre\lib\charsets.jar;C:\dev\jdk1.5.0_07\jre\lib\deploy.jar;C:\dev\jdk1.5.0_07\jre\lib\javaws.jar;C:\dev\jdk1.5.0_07\jre\lib\jce.jar;C:\dev\jdk1.5.0_07\jre\lib\jsse.jar;C:\dev\jdk1.5.0_07\jre\lib\plugin.jar;C:\dev\jdk1.5.0_07\jre\lib\rt.jar;C:\dev\jdk1.5.0_07\jre\lib\ext\dnsns.jar;C:\dev\jdk1.5.0_07\jre\lib\ext\localedata.jar;C:\dev\jdk1.5.0_07\jre\lib\ext\sunjce_provider.jar;C:\dev\jdk1.5.0_07\jre\lib\ext\sunpkcs11.jar;C:\projects\temporal\build\classes;C:\dev\kodo-4.0.1\lib\xml-apis.jar;C:\dev\kodo-4.0.1\lib\sqlline.jar;C:\dev\kodo-4.0.1\lib\jdbc2_0-stdext.jar;C:\dev\kodo-4.0.1\lib\xalan.jar;C:\dev\kodo-4.0.1\lib\jdo.jar;C:\dev\kodo-4.0.1\lib\kodo.jar;C:\dev\kodo-4.0.1\lib\jpa.jar;C:\dev\kodo-4.0.1\lib\xercesImpl.jar;C:\dev\kodo-4.0.1\lib\wldfchart.jar;C:\dev\kodo-4.0.1\lib\kodo-api.jar;C:\dev\kodo-4.0.1\lib\jdbc-hsql-1_8_0.jar;C:\dev\kodo-4.0.1\lib\jline.jar;C:\dev\kodo-4.0.1\lib\jca1.0.jar;C:\dev\kodo-4.0.1\lib\jndi.jar;C:\dev\kodo-4.0.1\lib\kodo-runtime.jar;C:\dev\kodo-4.0.1\lib\jta-spec1_0_1.jar;C:\dev\kodo-4.0.1\lib\kodo-wl81manage.jar;C:\dev\kodo-4.0.1\lib\kodo-jboss4manage.jar;C:\projects\temporal\build\config;C:\Program Files\JetBrains\IntelliJ IDEA 5.1\lib\idea_rt.jar" com.intellij.rt.execution.application.AppMain net.uk.roos.util.SeedDatabase
Using kodo configuration from resource: C:\projects\temporal\build\config\kodo.properties
0 TRACE [main] kodo.Runtime - Setting the given properties into configuration: {kodo.Log=DefaultLevel=WARN, Runtime=TRACE, Tool=TRACE, kodo.ConnectionPassword=, kodo.ConnectionURL=jdbc:hsqldb:file://c:/projects/temporal/db/temporaldb, javax.jdo.PersistenceManagerFactoryClass=kodo.jdo.PersistenceManagerFactoryImpl, kodo.MetaDataFactory=jdo, kodo.ConnectionUserName=sa, kodo.ConnectionDriverName=org.hsqldb.jdbcDriver}
281 INFO [main] kodo.Runtime - Starting Kodo 4.0.1
281 DEBUG [main] kodo.Runtime - License capabilities: "Kodo Standard Edition,Remote Commit Listeners,Kodo Community Edition,Datacache Plug-in,Enterprise Databases,Query Extensions,Performance Pack,Statement Batching,Kodo Enterprise Edition,Custom Fetch Groups,Managed Environment,Developer Tools,Custom DBDictionaries" Expiration: "-" Maintenance expiration: "-"
281 TRACE [main] kodo.Runtime - kodo.ManagementConfiguration: none
kodo.PersistenceServer: false
kodo.Compatibility: default
kodo.OrphanedKeyAction: log
kodo.jdbc.Schemas:
kodo.jdbc.LRSSize: query
kodo.DynamicDataStructs: false
kodo.RetryClassRegistration: false
kodo.jdbc.SchemaFactory: dynamic
kodo.ConnectionURL: jdbc:hsqldb:file://c:/projects/temporal/db/temporaldb
kodo.jdbc.SynchronizeMappings: false
kodo.BrokerImpl: default
kodo.ConnectionDriverName: org.hsqldb.jdbcDriver
kodo.MetaDataFactory: jdo
kodo.jdbc.MappingDefaults: jdo
kodo.ManagedRuntime: auto
kodo.QueryCompilationCache: true
kodo.ReadLockLevel: read
kodo.jdbc.FetchDirection: forward
kodo.DataCacheTimeout: -1
kodo.ClassResolver: default
kodo.ConnectionUserName: sa
kodo.jdbc.TransactionIsolation: default
kodo.IgnoreChanges: false
kodo.InverseManager: false
kodo.ConnectionRetainMode: on-demand
kodo.Sequence: table
kodo.SavepointManager: in-mem
kodo.ConnectionPassword:
kodo.AutoDetach:
kodo.TransactionMode: local
kodo.NontransactionalRead: true
kodo.DetachState: loaded
kodo.AutoClear: datastore
javax.jdo.PersistenceManagerFactoryClass: kodo.jdo.PersistenceManagerFactoryImpl
kodo.BrokerFactory: jdbc
kodo.Multithreaded: false
kodo.Log: DefaultLevel=WARN, Runtime=TRACE, Tool=TRACE
kodo.QueryCache: true
kodo.jdbc.UpdateManager: default
kodo.jdbc.ResultSetType: forward-only
kodo.ProxyManager: default
kodo.LockTimeout: -1
kodo.RetainState: true
kodo.RestoreState: immutable
kodo.FlushBeforeQueries: true
kodo.ConnectionFactoryMode: local
kodo.FetchBatchSize: -1
kodo.Optimistic: true
kodo.jdbc.EagerFetchMode: parallel
kodo.FetchGroups:
kodo.LockManager: pessimistic
kodo.jdbc.SubclassFetchMode: join
kodo.NontransactionalWrite: false
kodo.WriteLockLevel: write
Exception in thread "main" java.lang.ClassCastException: kodo.jdo.PersistenceManagerFactoryImpl
at kodo.runtime.KodoHelper.getPersistenceManagerFactory(KodoHelper.java:66)
at net.uk.roos.util.SeedDatabase.go(Unknown Source)
at net.uk.roos.util.SeedDatabase.main(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)
Process finished with exit code 1
Thanks and regards, Robin.
Robin Roos (robin at roos dot uk dot net)I solved my problem by defining a Properties object with the required configuration information and using JDOHelper.getPersistenceManagerFactory(Properties) instead of (File).
Kind regards, Robin. -
JDOQL Correlated Subquery - Bad SQL
Hi,
When I execute a JDOQL correlated subquery, the generated SQL is either
invalid or incorrect. Exactly what happens depends on the exact query, and
on the target database type, but I believe it all stems from the same
problem, which has to do with table aliasing.
If you need further details to reproduce this, please let me know. I'll be
glad to help in any way I can to get this situation remedied quickly, as I
am depending on this functionality. I have a test application to
demonstrate the problem.
I'm using Kodo 3.3.3 and application identity.
Paul Mogren
CommerceHubFor the record, this is in part due to a bug in Kodo's SQL92 joining.
See http://bugzilla.solarmetric.com/show_bug.cgi?id=1156
-Patrick
Paul Mogren wrote:
Certainly... Here's a simple example using Microsoft's JDBC Driver for SQL
Server 2000, and kodo.jdbc.sql.SQLServerDictionary, which produces invalid
SQL.
The query:
pm.newQuery(Container.class,
"(select from Entry entry where entries.contains(entry) &&
entry.containedId != 1).isEmpty()");
The classes:
class Contained {
private int id; //pk
class Container {
private int id; //pk
private Set entries = new HashSet(); //<Entry>
class Entry {
private int containerId; //pk
private int containedId; //pk
private Container container; //persistent-redundant
private Contained contained; //persistent-redundant
The result:
Incorrect syntax near the keyword 'WHERE'. {prepstmnt 31598780 SELECT
t0.container_id, t0.lock FROM WHERE (NOT EXISTS (SELECT DISTINCT
t2.contained_id, t2.container_id FROM dbo.entry t2 WHERE (t1.contained_id
= t2.contained_id AND t1.container_id = t2.container_id AND
t2.contained_id <> ?) AND t0.container_id = t1.container_id))
[params=(int) 1]} [code=156, state=HY000]
Patrick Linskey wrote:
Hi Paul,
Kodo's correlated subquery support does have some known limitations. Can
you post a sample JDOQL statement + corresponding SQL statement?
-Patrick
Paul Mogren wrote:
Hi,
When I execute a JDOQL correlated subquery, the generated SQL is either
invalid or incorrect. Exactly what happens depends on the exact query, and
on the target database type, but I believe it all stems from the same
problem, which has to do with table aliasing.
If you need further details to reproduce this, please let me know. I'll be
glad to help in any way I can to get this situation remedied quickly, as I
am depending on this functionality. I have a test application to
demonstrate the problem.
I'm using Kodo 3.3.3 and application identity.
Paul Mogren
CommerceHub -
Unit test fails after upgrading to Kodo 4.0.0 from 4.0.0-EA4
I have a group of 6 unit tests failing after upgrading to the new Kodo
4.0.0 (with BEA) from Kodo-4.0.0-EA4 (with Solarmetric). I'm getting
exceptions like the one at the bottom of this email. It seems to be an
interaction with the PostgreSQL driver, though I can't be sure. I
haven't changed my JDO configuration or the related classes in months
since I've been focusing on using the objects that have already been
defined. The .jdo, .jdoquery, and .java code are below the exception,
just in case there's something wrong in there. Does anyone have advice
as to how I might debug this?
Thanks,
Mark
Testsuite: edu.ucsc.whisper.test.integration.UserManagerQueryIntegrationTest
Tests run: 15, Failures: 0, Errors: 6, Time elapsed: 23.308 sec
Testcase:
testGetAllUsersWithFirstName(edu.ucsc.whisper.test.integration.UserManagerQueryIntegrationTest):
Caused an ERROR
The column index is out of range: 2, number of columns: 1.
<2|false|4.0.0> kodo.jdo.DataStoreException: The column index is out of
range: 2, number of columns: 1.
at
kodo.jdbc.sql.DBDictionary.newStoreException(DBDictionary.java:4092)
at kodo.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:82)
at kodo.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:66)
at kodo.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:46)
at
kodo.jdbc.kernel.SelectResultObjectProvider.handleCheckedException(SelectResultObjectProvider.java:176)
at
kodo.kernel.QueryImpl$PackingResultObjectProvider.handleCheckedException(QueryImpl.java:2460)
at
com.solarmetric.rop.EagerResultList.<init>(EagerResultList.java:32)
at kodo.kernel.QueryImpl.toResult(QueryImpl.java:1445)
at kodo.kernel.QueryImpl.execute(QueryImpl.java:1136)
at kodo.kernel.QueryImpl.execute(QueryImpl.java:901)
at kodo.kernel.QueryImpl.execute(QueryImpl.java:865)
at kodo.kernel.DelegatingQuery.execute(DelegatingQuery.java:787)
at kodo.jdo.QueryImpl.executeWithArray(QueryImpl.java:210)
at kodo.jdo.QueryImpl.execute(QueryImpl.java:137)
at
edu.ucsc.whisper.core.dao.JdoUserDao.findAllUsersWithFirstName(JdoUserDao.java:232)
at
edu.ucsc.whisper.core.manager.DefaultUserManager.getAllUsersWithFirstName(DefaultUserManager.java:252)
NestedThrowablesStackTrace:
org.postgresql.util.PSQLException: The column index is out of range: 2,
number of columns: 1.
at
org.postgresql.core.v3.SimpleParameterList.bind(SimpleParameterList.java:57)
at
org.postgresql.core.v3.SimpleParameterList.setLiteralParameter(SimpleParameterList.java:101)
at
org.postgresql.jdbc2.AbstractJdbc2Statement.bindLiteral(AbstractJdbc2Statement.java:2085)
at
org.postgresql.jdbc2.AbstractJdbc2Statement.setInt(AbstractJdbc2Statement.java:1133)
at
com.solarmetric.jdbc.DelegatingPreparedStatement.setInt(DelegatingPreparedStatement.java:390)
at
com.solarmetric.jdbc.PoolConnection$PoolPreparedStatement.setInt(PoolConnection.java:440)
at
com.solarmetric.jdbc.DelegatingPreparedStatement.setInt(DelegatingPreparedStatement.java:390)
at
com.solarmetric.jdbc.DelegatingPreparedStatement.setInt(DelegatingPreparedStatement.java:390)
at
com.solarmetric.jdbc.DelegatingPreparedStatement.setInt(DelegatingPreparedStatement.java:390)
at
com.solarmetric.jdbc.LoggingConnectionDecorator$LoggingConnection$LoggingPreparedStatement.setInt(LoggingConnectionDecorator.java:1
257)
at
com.solarmetric.jdbc.DelegatingPreparedStatement.setInt(DelegatingPreparedStatement.java:390)
at
com.solarmetric.jdbc.DelegatingPreparedStatement.setInt(DelegatingPreparedStatement.java:390)
at kodo.jdbc.sql.DBDictionary.setInt(DBDictionary.java:980)
at kodo.jdbc.sql.DBDictionary.setUnknown(DBDictionary.java:1299)
at kodo.jdbc.sql.SQLBuffer.setParameters(SQLBuffer.java:638)
at kodo.jdbc.sql.SQLBuffer.prepareStatement(SQLBuffer.java:539)
at kodo.jdbc.sql.SQLBuffer.prepareStatement(SQLBuffer.java:512)
at kodo.jdbc.sql.SelectImpl.execute(SelectImpl.java:332)
at kodo.jdbc.sql.SelectImpl.execute(SelectImpl.java:301)
at kodo.jdbc.sql.Union$UnionSelect.execute(Union.java:642)
at kodo.jdbc.sql.Union.execute(Union.java:326)
at kodo.jdbc.sql.Union.execute(Union.java:313)
at
kodo.jdbc.kernel.SelectResultObjectProvider.open(SelectResultObjectProvider.java:98)
at
kodo.kernel.QueryImpl$PackingResultObjectProvider.open(QueryImpl.java:2405)
at
com.solarmetric.rop.EagerResultList.<init>(EagerResultList.java:22)
at kodo.kernel.QueryImpl.toResult(QueryImpl.java:1445)
at kodo.kernel.QueryImpl.execute(QueryImpl.java:1136)
at kodo.kernel.QueryImpl.execute(QueryImpl.java:901)
at kodo.kernel.QueryImpl.execute(QueryImpl.java:865)
at kodo.kernel.DelegatingQuery.execute(DelegatingQuery.java:787)
at kodo.jdo.QueryImpl.executeWithArray(QueryImpl.java:210)
at kodo.jdo.QueryImpl.execute(QueryImpl.java:137)
at
edu.ucsc.whisper.core.dao.JdoUserDao.findAllUsersWithFirstName(JdoUserDao.java:232)
--- DefaultUser.java -------------------------------------------------
public class DefaultUser
implements User
/** The account username. */
private String username;
/** The account password. */
private String password;
/** A flag indicating whether or not the account is enabled. */
private boolean enabled;
/** The authorities granted to this account. */
private Set<Authority> authorities;
/** Information about the user, including their name and text that
describes them. */
private UserInfo userInfo;
/** The set of organizations where this user works. */
private Set<Organization> organizations;
--- DefaultUser.jdo --------------------------------------------------
<?xml version="1.0"?>
<!DOCTYPE jdo PUBLIC
"-//Sun Microsystems, Inc.//DTD Java Data Objects Metadata 2.0//EN"
"http://java.sun.com/dtd/jdo_2_0.dtd">
<jdo>
<package name="edu.ucsc.whisper.core">
<sequence name="user_id_seq"
factory-class="native(Sequence=user_id_seq)"/>
<class name="DefaultUser" detachable="true"
table="whisper_user" identity-type="datastore">
<datastore-identity sequence="user_id_seq" column="userId"/>
<field name="username">
<column name="username" length="80" jdbc-type="VARCHAR" />
</field>
<field name="password">
<column name="password" length="40" jdbc-type="CHAR" />
</field>
<field name="enabled">
<column name="enabled" />
</field>
<field name="userInfo" persistence-modifier="persistent"
default-fetch-group="true" dependent="true">
<extension vendor-name="jpox"
key="implementation-classes"
value="edu.ucsc.whisper.core.DefaultUserInfo" />
<extension vendor-name="kodo"
key="type"
value="edu.ucsc.whisper.core.DefaultUserInfo" />
</field>
<field name="authorities" persistence-modifier="persistent"
table="user_authorities"
default-fetch-group="true">
<collection
element-type="edu.ucsc.whisper.core.DefaultAuthority" />
<join column="userId" delete-action="cascade"/>
<element column="authorityId" delete-action="cascade"/>
</field>
<field name="organizations" persistence-modifier="persistent"
table="user_organizations" mapped-by="user"
default-fetch-group="true" dependent="true">
<collection
element-type="edu.ucsc.whisper.core.DefaultOrganization"
dependent-element="true"/>
<join column="userId"/>
<!--<element column="organizationId"/>-->
</field>
</class>
</package>
</jdo>
--- DefaultUser.jdoquery ---------------------------------------------
<?xml version="1.0"?>
<!DOCTYPE jdo PUBLIC
"-//Sun Microsystems, Inc.//DTD Java Data Objects Metadata 2.0//EN"
"http://java.sun.com/dtd/jdo_2_0.dtd">
<jdo>
<package name="edu.ucsc.whisper.core">
<class name="DefaultUser">
<query name="UserByUsername"
language="javax.jdo.query.JDOQL"><![CDATA[
SELECT UNIQUE FROM edu.ucsc.whisper.core.DefaultUser
WHERE username==searchName
PARAMETERS java.lang.String searchName
]]></query>
<query name="DisabledUsers"
language="javax.jdo.query.JDOQL"><![CDATA[
SELECT FROM edu.ucsc.whisper.core.DefaultUser WHERE
enabled==false
]]></query>
<query name="EnabledUsers"
language="javax.jdo.query.JDOQL"><![CDATA[
SELECT FROM edu.ucsc.whisper.core.DefaultUser WHERE
enabled==true
]]></query>
<query name="CountUsers"
language="javax.jdo.query.JDOQL"><![CDATA[
SELECT count( this ) FROM edu.ucsc.whisper.core.DefaultUser
]]></query>
</class>
</package>
</jdo>I'm sorry, I have no idea. I suggest sending a test case that
reproduces the problem to support. -
How to use a MAP whithout join table
Hello
I am still evaluating KODO ;-)
I am using kodo 3.1.2 with an evaluation version
linux (kernel 2.6)
SUN JDK 1.4.2_04
MYSQL MAX 4.0.18 -Max
IDEA 4.0.3 and ANT 1.5.4 (to be exhaustive)
I am wondering how to configure the following mapping involving a Map. :
public class Translation {
private String locale;
private String txt;
public class TranslatableDescription {
/**Map of Key=locale as String; Value = {@link Translation}*/
==> private Map translations = new HashMap(); <==
public void addATranslation(Translation t){
translations.put(t.getLocale(), t);
file package.jdo :
<?xml version="1.0"?>
<jdo>
<package name="data">
<class name="Translation"/>
<class name="TranslatableDescription">
<field name="translations">
<map key-type="java.lang.String"
value-type="tutorial.data.Translation"/>
<extension vendor-name="kodo" key="jdbc-key-size" value="10"/>
</field>
</class>
</package>
</jdo>
The default Mapping generate a join table : TRANS_TRANSLATION which works
fine, but I would like to remove this table by adding a
colonne in the "TRANSLATION" table containing the JDOID of the
TRANSLATIONDESCRIPTION owner of this TRANSLATION.
I have made some try like this one in the mapping file
<class name="TranslatableDescription">
<field name="translations">
<jdbc-field-map type="n-many-map" key-column="LOCALE"
ref-column.JDOID="OWNERJDOID" table="TRANSLATION0"
value-column.JDOID="JDOID"/>
</field>
The schema generated in my DB is correct but when I try to persist some
objects I have the following Exception :
727 INFO [main] kodo.jdbc.JDBC - Using dictionary class
"kodo.jdbc.sql.MySQLDictionary" (MySQL 4.0.18'-Max' ,MySQL-AB JDBC Driver
mysql-connector-java-3.0.10-stable ( $Date: 2004/01/13 21:56:18 $,
$Revision: 1.27.2.33 $ )).
Exception in thread "main" kodo.util.FatalDataStoreException: Invalid
argument value, message from server: "Duplicate entry '2' for key 1"
{prepstmnt 8549963 INSERT INTO TRANSLATION0 (JDOID, LOCALESTR, OWNERJDOID)
VALUES (?, ?, ?) [reused=0]} [code=1062, state=S1009]
NestedThrowables:
com.solarmetric.jdbc.ReportingSQLException: Invalid argument value,
message from server: "Duplicate entry '2' for key 1" {prepstmnt 8549963
INSERT INTO TRANSLATION0 (JDOID, LOCALESTR, OWNERJDOID) VALUES (?, ?, ?)
[reused=0]} [code=1062, state=S1009]
java.sql.BatchUpdateException: Invalid argument value, message from
server: "Duplicate entry '2' for key 1"
at kodo.jdbc.sql.SQLExceptions.getFatalDataStore(SQLExceptions.java:42)
at kodo.jdbc.sql.SQLExceptions.getFatalDataStore(SQLExceptions.java:24)
at kodo.jdbc.runtime.JDBCStoreManager.flush(JDBCStoreManager.java:594)
at
kodo.runtime.DelegatingStoreManager.flush(DelegatingStoreManager.java:152)
at
kodo.runtime.PersistenceManagerImpl.flushInternal(PersistenceManagerImpl.java:964)
at
kodo.runtime.PersistenceManagerImpl.beforeCompletion(PersistenceManagerImpl.java:813)
at kodo.runtime.LocalManagedRuntime.commit(LocalManagedRuntime.java:69)
at
kodo.runtime.PersistenceManagerImpl.commit(PersistenceManagerImpl.java:542)
at
tutorial.CreateTranslatableDescription.main(CreateTranslatableDescription.java:48)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at com.intellij.rt.execution.application.AppMain.main(Unknown Source)
I have the feeling that KODO does try to make diffent row in the table
"TRANSLATION0" for the TRANSLATION and the MAP.
So, is this kind of mapping supported by KODO and if yes, how can I
configure it.
Thank you for your help
NicolasSo, is this kind of mapping supported by KODO and if yes, how can I
configure it.It is not directly supported. You can fake it using a one-many mapping
(see thread: Externalizing Map to Collection of PC), but unless you must
map to an existing schema, it's probably not worth the effort. (Note:
also there is a bug that actually prevents this from working with 3.1.2;
the bug is fixed for 3.1.3, but it hasn't been released yet). -
Horizontal mapping not working in Kodo 4.1.2
Hello,
I am having troubles in trying to get the class mapping I want in Kodo 4.1.2.
I want to go from Kodo 3.3 to Kodo 4.1, and still in the evaluation process. Basically, all I want is to have my package.jdo files to work in Kodo 4.1, with the minimum modifications, before moving to JPA.
The mapping is defined is my package.jdo using the <extension vendor-name="kodo" key="jdbc-class-map" value="XXX"/> where XXX can be one of horizontal, base or flat (I dont use vertical in this applicaion). This element does not seem to be properly recognized by the new mapping tool, and all my classes are mapped in the same base table.
After some digging in the docs and in the examples provided, I found this <inheritance strategy="XXX"/> element, that can be put in my package.jdo file. This is not clearly said in the docs (it seems this element is only mentionned in the new orm DTD), but is used in the sample/jdo/horizontal/package.jdo file.
Then I modified my package.jdo files, with this new element, where XXX is one of subclass-table, new-table (with no <join/> nested element) or superclass-table. But the result is not the one expected : all the classes are mapped in the same table.
I then gave a try at the example provided, compiled, enhanced and mapped the sample/jdo/horizontal classes provided with the distribution, since this example covers exactly what I want to do. It seems to me that this example does not work either.
The package.jdo says :
<jdo>
<package name="samples.jdo.horizontal">
<sequence name="sjvm" factory-class="sjvm" strategy="nontransactional"/>
<class name="LastModified">
<inheritance strategy="subclass-table"/>
</class>
The mapping file I get says :
<mapping>
<package name="samples.jdo.horizontal">
<class name="LastModified">
<jdbc-class-map type="base" pk-column="ID" table="LASTMODIFIED"/>
<jdbc-version-ind type="version-number" column="VERSN"/>
<jdbc-class-ind type="in-class-name" column="TYP"/>
<field name="creationDate">
<jdbc-field-map type="value" column="CREATIONDATE"/>
</field>
<field name="lastModificationDate">
<jdbc-field-map type="value" column="LASTMODIFICATIONDATE"/>
</field>
</class>
The enhancement is made using jdoc, the mapping file is generated using the following command line (the DB is empty) :
mappingtool -a refresh -f mapping.xml samples.jdo.horizontal.LastModifiedI would expect an horizontal mapping, with a class element containing only a <jdbc-class-map type="horizontal"/> element, as it is the case if I use my Kodo 3.3 mapping tool.
I tried the enhancement / mapping file generation process with two configuration of the kodo.properties file : the first one with kodo3 as the Mapping Factory and the second with jdo. The result is the same in both cases. I verified by setting the log level to TRACE for the Tool what the factory used. In fact in both case, it is the MappingFileDeprecatedJDOMappingFactory, which seems weird to me.
Bytheway, setting the MappingFactory to jpa leads to the following IllegalArgumentException during enhancement :
Exception in thread "main" org.apache.openjpa.lib.util.ParseException: Instantiation of plugin "MetaDataFactory" with value "jpa" caused an error "java.lang.IllegalArgumentException : java.lang.ClassNotFoundException: jpa". The alias or class name may have been misspelled, or the class may not have be available in the class path. Valid aliases for this plugin are: [jdo, kodo3]
I'd be glad to get any hint if I'm wrong on anything, or any workaround / patch to get my case to work.
Thank you in advance,
JoseIf the same exact app and code works with 4.0 with the same ForeignKeyDeleteAction setting, I suggest that you open a case with support.
This property hasn't changed since 4.0
http://e-docs.bea.com/kodo/docs41/full/html/ref_guide_mapping_defaults.html
Laurent -
Relational queries through JDBC with the help of Kodo's metadata for O/R mapping
Due to JDOQL's limitations (inability to express joins, when relationships
are not modeled as object references), I find myself needing to drop down to
expressing some queries in SQL through JDBC. However, I still want my Java
code to remain independent of the O/R mapping. I would like to be able to
formulate the SQL without hardcoding any knowledge of the relational table
and column names, by using Kodo's metadata. After poking around the Kodo
Javadocs, it appears as though the relevant calls are as follows:
ClassMetaData cmd = ClassMetaData.getInstance(MyPCObject.class, pm);
FieldMetaData fmd = cmd.getDeclaredField( "myField" );
PersistenceManagerFactory pmf = pm.getPersistenceManagerFactory();
JDBCConfiguration conf = (JDBCConfiguration)
((EEPersistenceManagerFactory)pmf).getConfiguration();
ClassResolver resolver = pm.getClassResolver(MyPCObject.class);
Connector connector = new PersistenceManagerConnector(
(PersistenceManagerImpl) pm );
DBDictionary dict = conf.getDictionary( connector );
FieldMapping fm = ClassMapping.getFieldMapping(fmd, conf, resolver, dict);
Column[] cols = fm.getDataColumns();
Does that look about right?
Here's what I'm trying to do:
class Foo
String name; // application identity
String bar; // foreign key to Bar
class Bar
String name; // application identity
int weight;
Let's say I want to query for all Foo instances for which its bar.weight >
100. Clearly this is trivial to do in JDOQL, if Foo.bar is an object
reference to Bar. But there are frequently good reasons for modeling
relationships as above, for example when Foo and Bar are DTOs exposed by the
remote interface of an EJB. (Yeah, yeah, I'm lazy, using my
PersistenceCapable classes as both the DAOs and the DTOs.) But I still want
to do queries that navigate the relationship; it would be nice to do it in
JDOQL directly. I will also want to do other weird-ass queries that would
definitely only be expressible in SQL. Hence, I'll need Kodo's O/R mapping
metadata.
Is there anything terribly flawed with this logic?
BenI have a one point before I get to this:
There is nothing wrong with using PC instances as both DAO and DTO
objects. In fact, I strongly recommend this for most J2EE/JDO design.
However, there should be no need to expose the foreign key values... use
application identity to quickly reconstitute an object id (which can in
turn find the persistent version), or like the j2ee tutorial, store the
object id in some form (Object or String) and use that to re-find the
matching persistent instance at the EJB tier.
Otherwise, there is a much easier way of finding ClassMapping instances
and in turn FieldMapping instances (see ClassMapping.getInstance () in
the JavaDocs).
Ben Eng wrote:
Due to JDOQL's limitations (inability to express joins, when relationships
are not modeled as object references), I find myself needing to drop down to
expressing some queries in SQL through JDBC. However, I still want my Java
code to remain independent of the O/R mapping. I would like to be able to
formulate the SQL without hardcoding any knowledge of the relational table
and column names, by using Kodo's metadata. After poking around the Kodo
Javadocs, it appears as though the relevant calls are as follows:
ClassMetaData cmd = ClassMetaData.getInstance(MyPCObject.class, pm);
FieldMetaData fmd = cmd.getDeclaredField( "myField" );
PersistenceManagerFactory pmf = pm.getPersistenceManagerFactory();
JDBCConfiguration conf = (JDBCConfiguration)
((EEPersistenceManagerFactory)pmf).getConfiguration();
ClassResolver resolver = pm.getClassResolver(MyPCObject.class);
Connector connector = new PersistenceManagerConnector(
(PersistenceManagerImpl) pm );
DBDictionary dict = conf.getDictionary( connector );
FieldMapping fm = ClassMapping.getFieldMapping(fmd, conf, resolver, dict);
Column[] cols = fm.getDataColumns();
Does that look about right?
Here's what I'm trying to do:
class Foo
String name; // application identity
String bar; // foreign key to Bar
class Bar
String name; // application identity
int weight;
Let's say I want to query for all Foo instances for which its bar.weight >
100. Clearly this is trivial to do in JDOQL, if Foo.bar is an object
reference to Bar. But there are frequently good reasons for modeling
relationships as above, for example when Foo and Bar are DTOs exposed by the
remote interface of an EJB. (Yeah, yeah, I'm lazy, using my
PersistenceCapable classes as both the DAOs and the DTOs.) But I still want
to do queries that navigate the relationship; it would be nice to do it in
JDOQL directly. I will also want to do other weird-ass queries that would
definitely only be expressible in SQL. Hence, I'll need Kodo's O/R mapping
metadata.
Is there anything terribly flawed with this logic?
Ben
Steve Kim
[email protected]
SolarMetric Inc.
http://www.solarmetric.com -
Kodo 2.3.0 is painfully slow
Kodo 2.3.0 is painfully slow with Oracle database. It is doing left joins
repeatable reading the same data over and over again. It is so slow that it
is virtually impossible to use. kodo 2.2.x was lightning fast to compare
with 2.3Full time Professional Photographer
We use Lightroom on three workstations in our studio.
[Production workstation]
Alienware (2) Dual Core Opteron 285 2.61GHz
8 megs ram
Raid 0
Win 7 Ultimate - 64
NVidia GeForce GTX 260
[Presentation workstation]
Quadcore Dell - Vista Ulltimate
Raid 0
[Production workstation]
Quadcore Dell XPS 710 - Win XP Pro
Raid 0
All three workstations are running Lightroom 3. All are running LR3 with unacceptably slow performance when compared to LR 2.7.
I am putting LR 2.7 back on all three workstations for actual production work. A typical wedding has 3-5 thousand images to process. This has to be done quickly. LR 2.7 is very stable on all my systems and runs much faster than any other version of LR I have had.
LR 3.0 looks to be a fantastic program. BUT, version 3.0 is not ready for handling real world work flow at this time. I am looking forward to version 3.1. -
How to do left outer join in one-one mapping
I tried to do a left outer join between two tables. I specified
kodo.jdbc.DBDictionary: JoinSyntax=sql92 in kodo.properties. I used
ref-join-type="outer" in the package.mapping. However, I still see Kodo is
translating my queries using inner join. How can I force kodo to use outer
join (or maybe even to use left outer join) when translating my queries?
Thanks.Kodo will automatically use an outer join when eager-fetching a to-one
relation (unless you have set null-value="exception" on the field, in
which case Kodo knows it can use an inner join). There is no need to set
the ref-join type (in fact, that is only for when the foreign key
columns are in a joined table).
When you place criteria on a relation in a query, though, the relation
must exist to satisfy the query. For example, in the filter:
"relation.x == y"
The "relation" field must hold a related object to satisfy the
expression, just as in Java.
If you want the "relation" field to optionally be null, then write your
filter exactly as you would in Java:
"relation == null || relation.x == y"
Kodo will correctly use an outer join in this case because the filter
can be satisfied even when no related object exists. -
Abe, Patrick,
I was using Kodo for couple of months now. I think it is a very good product
and you are getting closer to complete feature set. I wonder if you could
share with us your plans for Kodo performance optimization.
In out discussion regarding extra roundtrips to database to resolve uncached
references you explained that it is due to the fact that you do not store
reference primary key in instance's filed store. If I understand correctly
it prevents you from issuing query on referenced table instead you have to
join referenced and referencing table which is slower. Also I noticed that
when running queries it does similar thing:
For example I have a Position which directly references OrgUnit, Role and
Member so org_unit_id, member_id and role_id are columns of position table.
I want to lookup all positions with particular role, member and org unit. I
would expect something like:
select ....
from position p
where p.org_unit_id = 100 and p.role_id=10 and p.member=133
instead I get
SELECT ....
FROM POSITION t0, MEMBER t2, ORG_UNIT t1, ROLE t3
WHERE t2.MEMBER_ID = 133 AND t0.MEMBER_ID = t2.MEMBER_ID AND
t1.ORG_UNIT_ID = 100 AND t0.ORG_UNIT_ID = t1.ORG_UNIT_ID AND
t3.ROLE_ID = 10 AND t0.ROLE_ID = t3.ROLE_ID
FOUR USELESS JOINS instead of select on single table
Another issue is updates. Right now it seems to me there is no update
tuuning - you always update all columns. It is not very efficient especially
when columns you update needlessly have indices, foreign keys constraints
etc. Also when people track changes to their data (for various data
exports/imports and synchronizations) it creates many extra transactions.
One case is particularly noticeable - when you need to update LOCK column
only you update every column. Specifically when I add to a collection of a
persistent class you would update all fields of the class itself (you only
need to update LOCK for concurrency purpose) even though I made no changes
to it
These are the most noticeable things.
Please let me know if you are interested in this kind of feedback. I will be
glad to dig-up more staff :-) as I will be comparing Kodo with another JDO
implementation which claims full support of JDO specs.
Alex"Alex Roytman" <[email protected]> writes:
Abe, Patrick,
I was using Kodo for couple of months now. I think it is a very good product
and you are getting closer to complete feature set. I wonder if you could
share with us your plans for Kodo performance optimization.Thank you. We're pleased with the direction that Kodo is going in, and
are glad that you and others on this newsgroup seem happy as well.
From the beginning, we decided to put off optimizations until the
product reached a certain level of maturity. There were two main reasons
for this decision. First, we find it to be bad practice to optimize
while coding, as you often end up optimizing unnecessary 'cold spots'.
Second, we did not want to spend time optimizing code that would not end
up in the final version.
As of the last preview release (2.2.0), I think that Kodo has pretty
much reached that level of maturity. Most of the changes that we
anticipate making to reach spec compliance (obviously barring any major
spec changes) revolve around Kodo's current Extent implementation, which
does not currently behave according to the spec. So, we are just now
trying to identify what needs optimization, and prioritizing these
needs. Major items include our overly zealous use of joins and
memory-efficient large result sets. We are also doing some profiling to
root out any potential hot spots in our algorithms.
Please let me know if you are interested in this kind of feedback. I will be
glad to dig-up more staff :-) as I will be comparing Kodo with another JDO
implementation which claims full support of JDO specs.We are very interested in feedback both regarding other inefficiencies
that you see and any other comparisons to other JDO implementations.
-Patrick
Patrick Linskey [email protected]
SolarMetric Inc. http://www.solarmetric.com -
Kodo 4.0.0EA3 JDOHelper.is...() state functions
I'm trying to write unit tests for some of my higher level classes, and I've run into trouble trying
to test functions that delete persistent objects. I'm using Spring Framework's
AbstractTransactionalSpringContextTests class as my harness (which derives from JUnit's TestCase).
It sets up a transaction before each test function and rolls the transaction back (by default, this
is editable) after each test function. Because of this, I decided to base the test on the results of
JDOHelper.isDelete( objectThatWasDeleted ). My tests fail though, and all of the JDOHelper.is...()
functions return false at all points during the test. I know things are getting deleted though,
because before the Spring created transaction is started, I create my own transaction and persist
some objects, and after the Spring transaction is finished (and the test case), I create another
transaction to remove them (both my transactions are committed). Even in the tear down function,
JDOHelper.is...() functions don't seem to work; for example, isDeleted() returns false even though
the object has been scheduled for deletion and is in fact deleted when the transaction commits.
Is this a known bug? I was under the impression that JDOHelper functions were working as of EA2 (I
know they weren't working before that and we had to use KodoHelper).
Thanks,
Mark
Here's the code in question:
* This function is called after the test and the transaction it ran in have been completed.
* By default, the transaction is rolled back, but this can be overridden. This function
* should ensure the tests have been cleaned up, including anything that was created by the
* companion function onSetUpBeforeTransaction().
* @see onSetUpBeforeTransaction()
protected void onTearDownAfterTransaction()
if( transactionManager != null )
getLogger().info( "Starting transaction for post-test tear down." );
TransactionStatus status =
transactionManager.getTransaction( new DefaultTransactionDefinition() );
if( status != null )
getLogger().info( "Transaction for post-test tear down has been created." );
UserManager userManager = (UserManager) applicationContext.getBean( "userManager" );
User userToAlter = userManager.getUser( USER_TO_ALTER_USERNAME );
userManager.removeUser( userToAlter );
getLogger().debug(
"userToAlter (Kodo) - isDirty = " + KodoJDOHelper.isDirty( userToAlter )
+ ", isNew = " + KodoJDOHelper.isNew( userToAlter )
+ ", isPersistent = " + KodoJDOHelper.isPersistent( userToAlter )
+ ", isDeleted = " + KodoJDOHelper.isDeleted( userToAlter ) );
getLogger().debug( "userToAlter - isDirty = " + JDOHelper.isDirty( userToAlter )
+ ", isNew = " + JDOHelper.isNew( userToAlter )
+ ", isPersistent = " + JDOHelper.isPersistent( userToAlter )
+ ", isDeleted = " + JDOHelper.isDeleted( userToAlter ) );
try
transactionManager.commit( status );
finally
status = null;
else
getLogger().info( "Could not create transaction for post-test tear down."
+ " Superclass' transactionManager is null." );
And here's the log output (I've put blank lines around the relevant output):
2005-11-10 12:50:17,669 INFO [edu.ucsc.whisper.test.integration.UserManagerIntegrationTest] -
<Rolled back transaction after test execution>
2005-11-10 12:50:17,669 INFO [edu.ucsc.whisper.test.integration.UserManagerIntegrationTest] -
<Starting transaction for post-test tear down.>
2005-11-10 12:50:17,670 DEBUG [org.springframework.orm.jdo.JdoTransactionManager] - <Using
transaction object [org.springframework.orm.jdo.JdoTransactionManager$JdoTransactionObject@82d44b]>
2005-11-10 12:50:17,670 DEBUG [org.springframework.orm.jdo.JdoTransactionManager] - <Creating new
transaction with name [null]>
2005-11-10 12:50:17,670 DEBUG [org.springframework.orm.jdo.JdoTransactionManager] - <Opened new
PersistenceManager [kodo.jdo.PersistenceManagerImpl@3faa8d] for JDO transaction>
2005-11-10 12:50:17,670 DEBUG [org.springframework.orm.jdo.JdoTransactionManager] - <Exposing JDO
transaction as JDBC transaction
[org.springframework.orm.jdo.DefaultJdoDialect$DataStoreConnectionHandle@285701]>
2005-11-10 12:50:17,671 DEBUG
[org.springframework.transaction.support.TransactionSynchronizationManager] - <Bound value
[org.springframework.jdbc.datasource.ConnectionHolder@681dea] for key [datasource 9833630] to thread
[main]>
2005-11-10 12:50:17,671 DEBUG
[org.springframework.transaction.support.TransactionSynchronizationManager] - <Bound value
[org.springframework.orm.jdo.PersistenceManagerHolder@8424bd] for key
[kodo.jdo.PersistenceManagerFactoryImpl@aa994e] to thread [main]>
2005-11-10 12:50:17,671 DEBUG
[org.springframework.transaction.support.TransactionSynchronizationManager] - <Initializing
transaction synchronization>
2005-11-10 12:50:17,671 INFO [edu.ucsc.whisper.test.integration.UserManagerIntegrationTest] -
<Transaction for post-test tear down has been created.>
2005-11-10 12:50:17,671 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory]
- <Returning cached instance of singleton bean 'userManager'>
2005-11-10 12:50:17,671 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory]
- <Bean with name 'userManager' is a factory bean>
2005-11-10 12:50:17,671 DEBUG [org.springframework.transaction.interceptor.TransactionInterceptor] -
<Getting transaction for edu.ucsc.whisper.core.UserManager.getUser>
2005-11-10 12:50:17,671 DEBUG
[org.springframework.transaction.support.TransactionSynchronizationManager] - <Retrieved value
[org.springframework.orm.jdo.PersistenceManagerHolder@8424bd] for key
[kodo.jdo.PersistenceManagerFactoryImpl@aa994e] bound to thread [main]>
2005-11-10 12:50:17,671 DEBUG [org.springframework.orm.jdo.JdoTransactionManager] - <Found
thread-bound PersistenceManager [kodo.jdo.PersistenceManagerImpl@3faa8d] for JDO transaction>
2005-11-10 12:50:17,671 DEBUG
[org.springframework.transaction.support.TransactionSynchronizationManager] - <Retrieved value
[org.springframework.jdbc.datasource.ConnectionHolder@681dea] for key [datasource 9833630] bound to
thread [main]>
2005-11-10 12:50:17,671 DEBUG [org.springframework.orm.jdo.JdoTransactionManager] - <Using
transaction object [org.springframework.orm.jdo.JdoTransactionManager$JdoTransactionObject@87f48e]>
2005-11-10 12:50:17,671 DEBUG [org.springframework.orm.jdo.JdoTransactionManager] - <Participating
in existing transaction>
2005-11-10 12:50:17,671 DEBUG
[org.springframework.transaction.support.TransactionSynchronizationManager] - <Retrieved value
[org.springframework.orm.jdo.PersistenceManagerHolder@8424bd] for key
[kodo.jdo.PersistenceManagerFactoryImpl@aa994e] bound to thread [main]>
2005-11-10 12:50:17,672 DEBUG [kodo.Query] - <executing query: [SELECT UNIQUE FROM
edu.ucsc.whisper.core.DefaultUser WHERE username==searchName
PARAMETERS java.lang.String searchName] with parameters: {searchName=userToAlter}>
2005-11-10 12:50:17,674 DEBUG [kodo.jdbc.JDBC] - <<t 977184> connection pool: active=0, idle=1>
2005-11-10 12:50:17,674 DEBUG [kodo.jdbc.JDBC] - <<t 977184, conn 3700728> checkout>
2005-11-10 12:50:17,674 DEBUG [kodo.jdbc.JDBC] - <<t 977184> prepared statement cache: size=8,
max=50, requests=12, hits=4, created=8, redundant=0, overflow=0, leaked=0>
2005-11-10 12:50:17,677 DEBUG [kodo.jdbc.SQL] - <<t 977184, conn 3700728> [3 ms] executing prepstmnt
1168959 SELECT t0.userId, t0.VERSN, t0.enabled, t0.password, t1.userInfoId, t1.VERSN, t1.aboutText,
t1.familyName, t1.firstName, t1.gender, t1.namePrefix, t1.nameSuffix, t1.otherNames, t2.userId,
t2.VERSN, t2.enabled, t2.password, t2.USERINFO, t2.username, t0.username FROM whisper_user t0 LEFT
OUTER JOIN userinfo t1 ON t0.USERINFO = t1.userInfoId LEFT OUTER JOIN whisper_user t2 ON
t1.userInfoId = t2.USERINFO WHERE (t0.username = ?) [params=(String) userToAlter] [reused=1]>
2005-11-10 12:50:17,690 DEBUG [kodo.jdbc.SQL] - <<t 977184, conn 3700728> [3 ms] executing prepstmnt
4297359 SELECT t0.previousName, t0.nameOrder FROM userInfo_PreviousNames t0 WHERE t0.userInfoId = ?
ORDER BY t0.nameOrder ASC [params=(long) 1] [reused=0]>
2005-11-10 12:50:17,693 DEBUG [kodo.jdbc.SQL] - <<t 977184, conn 3700728> [2 ms] executing prepstmnt
16585718 SELECT t1.authorityId, t1.VERSN, t1.authority FROM user_authorities t0 INNER JOIN
authorities t1 ON t0.authorityId = t1.authorityId WHERE t0.userId = ? [params=(long) 1] [reused=0]>
2005-11-10 12:50:17,697 DEBUG [kodo.jdbc.SQL] - <<t 977184, conn 3700728> [3 ms] executing prepstmnt
11277980 SELECT t0.organizationId, t0.VERSN, t0.city, t0.country, t0.isPrimary, t0.orgName,
t0.positionTitle, t0.postalCode, t0.state, t0.streetAddress1, t0.streetAddress2, t0.streetAddress3,
t0.userId FROM organization t0 WHERE t0.userId = ? [params=(long) 1] [reused=0]>
2005-11-10 12:50:17,698 DEBUG [kodo.jdbc.JDBC] - <<t 977184, conn 3700728> return>
2005-11-10 12:50:17,698 DEBUG [kodo.jdbc.JDBC] - <<t 977184, conn 3700728> [0 ms] close>
2005-11-10 12:50:17,698 DEBUG [org.springframework.transaction.interceptor.TransactionInterceptor] -
<Invoking commit for transaction on edu.ucsc.whisper.core.UserManager.getUser>
2005-11-10 12:50:17,698 DEBUG [org.springframework.transaction.interceptor.TransactionInterceptor] -
<Getting transaction for edu.ucsc.whisper.core.UserManager.removeUser>
2005-11-10 12:50:17,698 DEBUG
[org.springframework.transaction.support.TransactionSynchronizationManager] - <Retrieved value
[org.springframework.orm.jdo.PersistenceManagerHolder@8424bd] for key
[kodo.jdo.PersistenceManagerFactoryImpl@aa994e] bound to thread [main]>
2005-11-10 12:50:17,698 DEBUG [org.springframework.orm.jdo.JdoTransactionManager] - <Found
thread-bound PersistenceManager [kodo.jdo.PersistenceManagerImpl@3faa8d] for JDO transaction>
2005-11-10 12:50:17,698 DEBUG
[org.springframework.transaction.support.TransactionSynchronizationManager] - <Retrieved value
[org.springframework.jdbc.datasource.ConnectionHolder@681dea] for key [datasource 9833630] bound to
thread [main]>
2005-11-10 12:50:17,698 DEBUG [org.springframework.orm.jdo.JdoTransactionManager] - <Using
transaction object [org.springframework.orm.jdo.JdoTransactionManager$JdoTransactionObject@ba0b12]>
2005-11-10 12:50:17,699 DEBUG [org.springframework.orm.jdo.JdoTransactionManager] - <Participating
in existing transaction>
2005-11-10 12:50:17,700 DEBUG
[org.springframework.transaction.support.TransactionSynchronizationManager] - <Retrieved value
[org.springframework.orm.jdo.PersistenceManagerHolder@8424bd] for key
[kodo.jdo.PersistenceManagerFactoryImpl@aa994e] bound to thread [main]>
2005-11-10 12:50:17,702 DEBUG
[org.springframework.transaction.support.TransactionSynchronizationManager] - <Retrieved value
[org.springframework.orm.jdo.PersistenceManagerHolder@8424bd] for key
[kodo.jdo.PersistenceManagerFactoryImpl@aa994e] bound to thread [main]>
2005-11-10 12:50:17,702 DEBUG [org.springframework.transaction.interceptor.TransactionInterceptor] -
<Invoking commit for transaction on edu.ucsc.whisper.core.UserManager.removeUser>
2005-11-10 12:50:17,702 DEBUG [edu.ucsc.whisper.test.integration.UserManagerIntegrationTest] -
<userToAlter (Kodo) - isDirty = false, isNew = false, isPersistent = false, isDeleted = false>
2005-11-10 12:50:17,702 DEBUG [edu.ucsc.whisper.test.integration.UserManagerIntegrationTest] -
<userToAlter - isDirty = false, isNew = false, isPersistent = false, isDeleted = false>
2005-11-10 12:50:17,703 DEBUG [org.springframework.orm.jdo.JdoTransactionManager] - <Triggering
beforeCommit synchronization>
2005-11-10 12:50:17,703 DEBUG [org.springframework.orm.jdo.JdoTransactionManager] - <Triggering
beforeCompletion synchronization>
2005-11-10 12:50:17,703 DEBUG [org.springframework.orm.jdo.JdoTransactionManager] - <Initiating
transaction commit>
2005-11-10 12:50:17,703 DEBUG [org.springframework.orm.jdo.JdoTransactionManager] - <Committing JDO
transaction on PersistenceManager [kodo.jdo.PersistenceManagerImpl@3faa8d]>
2005-11-10 12:50:17,703 DEBUG [kodo.jdbc.JDBC] - <<t 977184> connection pool: active=0, idle=1>
2005-11-10 12:50:17,703 DEBUG [kodo.jdbc.JDBC] - <<t 977184, conn 3700728> checkout>
2005-11-10 12:50:17,703 DEBUG [kodo.jdbc.JDBC] - <<t 977184> prepared statement cache: size=11,
max=50, requests=16, hits=5, created=11, redundant=0, overflow=0, leaked=0>
2005-11-10 12:50:17,705 DEBUG [kodo.jdbc.SQL] - <<t 977184, conn 3700728> [1 ms] executing prepstmnt
1104991 DELETE FROM userInfo_PreviousNames WHERE userInfoId = ? [params=(long) 1] [reused=0]>
2005-11-10 12:50:17,706 DEBUG [kodo.jdbc.SQL] - <<t 977184, conn 3700728> [1 ms] executing prepstmnt
15986263 DELETE FROM user_authorities WHERE authorityId = ? [params=(long) 1] [reused=0]>
2005-11-10 12:50:17,708 DEBUG [kodo.jdbc.SQL] - <<t 977184, conn 3700728> [1 ms] executing prepstmnt
10794796 DELETE FROM user_authorities WHERE userId = ? [params=(long) 1] [reused=0]>
2005-11-10 12:50:17,710 DEBUG [kodo.jdbc.SQL] - <<t 977184, conn 3700728> [2 ms] executing prepstmnt
16100636 DELETE FROM authorities WHERE authorityId = ? AND VERSN = ? [params=(long) 1, (int) 1]
[reused=0]>
2005-11-10 12:50:17,711 DEBUG [kodo.jdbc.SQL] - <<t 977184, conn 3700728> [1 ms] executing prepstmnt
3677634 DELETE FROM userinfo WHERE userInfoId = ? AND VERSN = ? [params=(long) 1, (int) 1] [reused=0]>
2005-11-10 12:50:17,713 DEBUG [kodo.jdbc.SQL] - <<t 977184, conn 3700728> [1 ms] executing prepstmnt
2745891 DELETE FROM whisper_user WHERE userId = ? AND VERSN = ? [params=(long) 1, (int) 1] [reused=0]>
2005-11-10 12:50:17,828 DEBUG [kodo.jdbc.JDBC] - <<t 977184, conn 3700728> [115 ms] commit>
2005-11-10 12:50:17,829 DEBUG [kodo.jdbc.JDBC] - <<t 977184, conn 3700728> return>
2005-11-10 12:50:17,829 DEBUG [kodo.jdbc.JDBC] - <<t 977184, conn 3700728> [1 ms] close>
2005-11-10 12:50:17,830 DEBUG [org.springframework.orm.jdo.JdoTransactionManager] - <Triggering
afterCompletion synchronization>
2005-11-10 12:50:17,830 DEBUG
[org.springframework.transaction.support.TransactionSynchronizationManager] - <Clearing transaction
synchronization>
2005-11-10 12:50:17,830 DEBUG
[org.springframework.transaction.support.TransactionSynchronizationManager] - <Removed value
[org.springframework.orm.jdo.PersistenceManagerHolder@8424bd] for key
[kodo.jdo.PersistenceManagerFactoryImpl@aa994e] from thread [main]>
2005-11-10 12:50:17,830 DEBUG
[org.springframework.transaction.support.TransactionSynchronizationManager] - <Removed value
[org.springframework.jdbc.datasource.ConnectionHolder@681dea] for key [datasource 9833630] from
thread [main]>
2005-11-10 12:50:17,831 DEBUG [org.springframework.orm.jdo.JdoTransactionManager] - <Closing JDO
PersistenceManager [kodo.jdo.PersistenceManagerImpl@3faa8d] after transaction>
2005-11-10 12:50:17,831 DEBUG [org.springframework.orm.jdo.PersistenceManagerFactoryUtils] -
<Closing JDO PersistenceManager>Abe White wrote:
You need to make sure that when you enhance, you include JDO
enhancement, not just the base Kodo enhancement. Now that Kodo 4
supports EJB 3 users who might not want JDO, it doesn't enhance-in
dependencies on JDO unless you ask it to.
If you enhance on the command line, that means using the "jdoc" command
rather than "kodoc" ("jdoc" is actually just a shortcut for "kodoc -jdo
true"). If you use the PCEnhancerTask, it means setting the jdoEnhance
attribute:
<taskdef name="kodoc" classname="kodo.ant.PCEnhancer"/>
<kodoc jdoEnhance="true">
</kodoc>So, what are the primary differences between the enhancement done for EJB3
and JDO? I gather that "base Kodo enhancement" is EJB3.
Scott -
Kodo JDO with JCA provided by Jencks in Tomcat
I'm trying to use both JDO and JCR (Apache's Jackrabbit) in my project. Both support XA
Transactions, and my understanding is that to best ensure data integrity, I should start using them.
Currently, I'm running under Tomcat using the SpringFramework support for transactions. I'd like to
continue running in Tomcat because I already understand that environment and the other app-servers
all feel heavyweight by comparison - all I need is JNDI and XA Transactions. Tomcat itself doesn't
support XA Transactions and JCA, but the open source project jencks is able to provide JCA support
within Tomcat.
I've been looking at the Deployment section of the JDO reference guide (Chapter 8). If I'm reading
this right, all I need to do is set two properties in the jdo.properties file: kodo.TransactionMode
and kodo.ManagedRuntime.
I've done that in my project:
kodo.TransactionMode: managed
kodo.ManagedRuntime: invocation(
TransactionManagerMethod=edu.ucsc.whisper.transaction.KodoTransactionAccess.getTransactionManager )
The getTransactionManager() is a static function that returns the
javax.transaction.TransactionManager provided by Spring's JtaTransactionManager.
I have a unit test that checks the application's initialization process, and I've been using that to
work my way into JCA transactions. Based on that test, this seems to be working. My question is this:
Is it really that simple?
Don't get me wrong, I'll be thrilled if it is, but from everything I'm seeing about configuring the
"Big Iron" app servers (WebLogic, JBoss, etc.), it just seems like adding two properties is too easy
and that I'm probably missing something significant in the process. Can anyone confirm whether or
not I'm on the right track here?
I'm working on setting this up for my heavier-duty integration tests, but I'm concerned that if I am
missing something, I've done just enough to fake Kodo out and that it isn't actually working under
the hood.
Thanks,
MarkAbe White wrote:
I would be surprised if your transaction manager and JDBC driver
configured themselves for XA automatically, since it imposes some
overhead and is rarely actually needed. In particular, you typically
need an XADataSource for XA transactions, rather than just using the
standard JDBC driver through the DriverManager (as Kodo does internally
when you specify ConnectionDriverName). So I suggest you consult their
documentation. As far as Kodo is concerned, though, as long as you've
set the TransactionMode, ManagedRuntime,
DataSourceMode/ConnectionFactoryMode (depending on Kodo version), and
are using an XA DataSource, you are all set.Hi Abe,
I've been able to get Spring configured so that it uses its JtaTransactionManager, and I have Kodo
setup with the TransactionMode as Managed and the ManagedRuntime is configured to use a static
method I created that returns the TransactionManager. In my logs, I can see Kodo accessing a
non-null instance of the TransactionManager class through this method. The problem that I'm getting
is that the behavior in my unit and integration tests is different than the behavior I'm seeing when
running in Tomcat, even though the Spring and Kodo configuration are nearly identical (Kodo accesses
a different database in Tomcat than it does in testing, other than that, the configuration is the
same). All the unit and integration tests pass; this requires transactions to be created, data
written to the database through Kodo, and then read back through Kodo in a new transaction. When I
deploy the web-app to Tomcat though, Kodo suddenly thinks its running without transactions. Reading
from the database works fine because I've got non-transactional reads turned on, but as soon as I
try to alter any field of a persisted object, Kodo throws an InvalidStateException saying it doesn't
have a transaction. I've included my log output below to demonstrate.
The only thing I haven't done yet, based on your previous message, is configure my database driver
for access through JNDI within Tomcat. Would that cause errors like this, or should I be looking
elsewhere?
My jdo.properties file contains these settings:
# For use of JDOHelper
javax.jdo.PersistenceManagerFactoryClass: kodo.jdo.PersistenceManagerFactoryImpl
# For Kodo JDO 4.0 EA2 and higher
javax.jdo.option.Connection2DriverName: org.postgresql.Driver
javax.jdo.option.Connection2UserName: ------------
javax.jdo.option.Connection2Password: ------------
javax.jdo.option.Connection2URL: jdbc:postgresql://127.0.0.1:5432/my_db
javax.jdo.option.Optimistic: true
javax.jdo.option.RetainState: true
javax.jdo.option.NontransactionalRead: true
kodo.FlushBeforeQueries=true
# For JCA Transaction support
kodo.TransactionMode: managed
kodo.ManagedRuntime: invocation(
TransactionManagerMethod=edu.ucsc.whisper.transaction.KodoTransactionAccess.getTransactionManager )
Thanks,
Mark
2006-04-04 02:03:13,891 DEBUG [org.springframework.transaction.interceptor.TransactionInterceptor] -
<mdslog - TransactionInterceptor starting create if necessary>
2006-04-04 02:03:13,891 DEBUG [org.springframework.transaction.interceptor.TransactionInterceptor] -
<mdslog - TransactionAspectSupport begin createTransactionIfNecessary()>
2006-04-04 02:03:13,891 DEBUG [org.springframework.transaction.interceptor.TransactionInterceptor] -
<Getting transaction for edu.ucsc.whisper.service.UserService.setUserInformation>
2006-04-04 02:03:13,892 DEBUG [org.springframework.transaction.jta.JtaTransactionManager] - <mdslog
- AbstractPlatformTransactionManager begin getTransaction>
2006-04-04 02:03:13,892 DEBUG [org.springframework.transaction.jta.JtaTransactionManager] - <Using
transaction object [org.springframework.transaction.jta.JtaTransactionObject@42b645]>
2006-04-04 02:03:13,892 DEBUG [org.springframework.transaction.jta.JtaTransactionManager] -
<Creating new transaction with name [edu.ucsc.whisper.service.UserService.setUserInformation]>
2006-04-04 02:03:13,892 DEBUG [org.springframework.transaction.jta.JtaTransactionManager] - <mdslog
- JtaTransactionManager begin doBegin>
2006-04-04 02:03:13,892 DEBUG [org.springframework.transaction.jta.JtaTransactionManager] - <mdslog
- JtaTransactionManager end doBegin>
2006-04-04 02:03:13,892 DEBUG [org.springframework.transaction.jta.JtaTransactionManager] - <mdslog
- AbstractPlatformTransactionManager end getTransaction>
2006-04-04 02:03:13,892 DEBUG [org.springframework.transaction.jta.JtaTransactionManager] - <mdslog
- AbstractPlatformTransactionManager begin newTransactionStatus>
2006-04-04 02:03:13,892 DEBUG
[org.springframework.transaction.support.TransactionSynchronizationManager] - <Initializing
transaction synchronization>
2006-04-04 02:03:13,892 DEBUG [org.springframework.transaction.jta.JtaTransactionManager] - <mdslog
- AbstractPlatformTransactionManager end newTransactionStatus>
2006-04-04 02:03:13,892 DEBUG [org.springframework.transaction.interceptor.TransactionInterceptor] -
<mdslog - TransactionAspectSupport end createTransactionIfNecessary()>
2006-04-04 02:03:13,892 DEBUG [org.springframework.transaction.interceptor.TransactionInterceptor] -
<mdslog - TransactionInterceptor finished create if necessary>
2006-04-04 02:03:13,892 INFO [edu.ucsc.whisper.service.DefaultUserService] - <setUserInformation begin>
2006-04-04 02:03:13,892 DEBUG [org.springframework.web.context.support.XmlWebApplicationContext] -
<Publishing event in context [WebApplicationContext for namespace 'xfire-servlet']:
org.acegisecurity.event.authorization.PublicInvocationEvent[source=invocation: method 'getUser',
arguments [mark]; target is of class [edu.ucsc.whisper.core.manager.DefaultUserManager]]>
2006-04-04 02:03:13,892 DEBUG [org.springframework.web.context.support.XmlWebApplicationContext] -
<Publishing event in context [Root WebApplicationContext]:
org.acegisecurity.event.authorization.PublicInvocationEvent[source=invocation: method 'getUser',
arguments [mark]; target is of class [edu.ucsc.whisper.core.manager.DefaultUserManager]]>
2006-04-04 02:03:13,892 DEBUG [org.springframework.orm.jdo.PersistenceManagerFactoryUtils] -
<Opening JDO PersistenceManager, factory = kodo.jdo.PersistenceManagerFactoryImpl@c2c9af>
2006-04-04 02:03:13,893 DEBUG [org.springframework.orm.jdo.PersistenceManagerFactoryUtils] - <New
JDO PersistenceManager = kodo.jdo.PersistenceManagerImpl@cc70c2, factory =
kodo.jdo.PersistenceManagerFactoryImpl@c2c9af>
2006-04-04 02:03:13,893 DEBUG [org.springframework.orm.jdo.PersistenceManagerFactoryUtils] -
<Registering transaction synchronization for JDO PersistenceManager>
2006-04-04 02:03:13,893 DEBUG
[org.springframework.transaction.support.TransactionSynchronizationManager] - <mdslog -
TransactionSynchronizationManager registerSynchronization -
org.springframework.orm.jdo.PersistenceManagerFactoryUtils$PersistenceManagerSynchronization@ff0f8a>
2006-04-04 02:03:13,893 DEBUG
[org.springframework.transaction.support.TransactionSynchronizationManager] - <Bound value
[org.springframework.orm.jdo.PersistenceManagerHolder@552f12] for key
[kodo.jdo.PersistenceManagerFactoryImpl@c2c9af] to thread [http-8443-Processor24]>
2006-04-04 02:03:13,893 DEBUG
[org.springframework.transaction.support.TransactionSynchronizationManager] - <Retrieved value
[org.springframework.orm.jdo.PersistenceManagerHolder@552f12] for key
[kodo.jdo.PersistenceManagerFactoryImpl@c2c9af] bound to thread [http-8443-Processor24]>
2006-04-04 02:03:13,893 DEBUG [org.springframework.orm.jdo.PersistenceManagerFactoryUtils] -
<Persistence manager kodo.jdo.PersistenceManagerImpl@cc70c2, factory
kodo.jdo.PersistenceManagerFactoryImpl@c2c9af is transactional: true>
2006-04-04 02:03:13,893 DEBUG [kodo.Query] - <Executing query: [SELECT UNIQUE FROM
edu.ucsc.whisper.core.DefaultUser WHERE username==searchName
PARAMETERS java.lang.String searchName] with parameters: {searchName=mark}>
2006-04-04 02:03:13,894 DEBUG [kodo.jdbc.JDBC] - <<t 11706420> connection pool: active=0, idle=1>
2006-04-04 02:03:13,894 DEBUG [kodo.jdbc.JDBC] - <<t 11706420, conn 15885558> checkout>
2006-04-04 02:03:13,895 DEBUG [kodo.jdbc.JDBC] - <<t 11706420> prepared statement cache: size=9,
max=50, requests=17, hits=8, created=9, redundant=0, overflow=0, leaked=0>
2006-04-04 02:03:13,902 DEBUG [kodo.jdbc.SQL] - <<t 11706420, conn 15885558> [5 ms] executing
prepstmnt 6033738 SELECT t0.userId, t0.TYP, t0.VERSN, t0.enabled, t0.password, t1.userInfoId,
t1.TYPE, t1.VERSN, t1.aboutText, t1.familyName, t1.firstName, t1.gender, t1.namePrefix,
t1.nameSuffix, t1.otherNames, t2.userId, t2.TYP, t2.VERSN, t2.enabled, t2.password, t2.USERINFO,
t2.username, t0.username FROM whisper_user t0 LEFT OUTER JOIN userinfo t1 ON t0.USERINFO =
t1.userInfoId LEFT OUTER JOIN whisper_user t2 ON t1.userInfoId = t2.USERINFO WHERE (t0.username = ?)
[params=(String) mark] [reused=3]>
2006-04-04 02:03:13,906 DEBUG [kodo.jdbc.SQL] - <<t 11706420, conn 15885558> [2 ms] executing
prepstmnt 12702178 SELECT t0.nameOrder, t0.previousName FROM userInfo_PreviousNames t0 WHERE
t0.userInfoId = ? ORDER BY t0.nameOrder ASC [params=(long) 2] [reused=3]>
2006-04-04 02:03:13,908 DEBUG [kodo.jdbc.SQL] - <<t 11706420, conn 15885558> [1 ms] executing
prepstmnt 7374726 SELECT t1.authorityId, t1.TYP, t1.VERSN, t1.authority FROM user_authorities t0
INNER JOIN authorities t1 ON t0.authorityId = t1.authorityId WHERE t0.userId = ? [params=(long) 2]
[reused=3]>
2006-04-04 02:03:13,912 DEBUG [kodo.jdbc.SQL] - <<t 11706420, conn 15885558> [2 ms] executing
prepstmnt 1745355 SELECT t0.organizationId, t0.TYPE, t0.VERSN, t0.city, t0.country, t0.isPrimary,
t0.orgName, t0.positionTitle, t0.postalCode, t0.state, t0.streetAddress1, t0.streetAddress2,
t0.streetAddress3, t0.userId FROM organization t0 WHERE t0.userId = ? [params=(long) 2] [reused=3]>
2006-04-04 02:03:13,912 DEBUG [kodo.jdbc.JDBC] - <<t 11706420, conn 15885558> return>
2006-04-04 02:03:13,912 DEBUG [kodo.jdbc.JDBC] - <<t 11706420, conn 15885558> [0 ms] close>
2006-04-04 02:03:13,913 INFO [edu.ucsc.whisper.security.WhisperAccessDecisionManager] - <voting on
access to: invocation: method 'getUserInfoForUser', arguments [{DefaultUser: username=mark;
password=871deb9e1c3dd967da1d4f6d01999eb71a4eab71; isEnabled=true}]; target is of class
[edu.ucsc.whisper.core.manager.DefaultUserManager], with auth:
edu.ucsc.whisper.security.WhisperClientAuthenticationToken@798d8: Username: {DefaultUser:
username=mark; password=871deb9e1c3dd967da1d4f6d01999eb71a4eab71; isEnabled=true}; Password:
[PROTECTED]; Authenticated: true; Details: null; Granted Authorities: {DefaultAuthority:
authority=ROLE_USER}>
2006-04-04 02:03:13,913 INFO [edu.ucsc.whisper.security.UserIsOwnerOrAdminVoter] - <voting with auth
= edu.ucsc.whisper.security.WhisperClientAuthenticationToken@798d8: Username: {DefaultUser:
username=mark; password=871deb9e1c3dd967da1d4f6d01999eb71a4eab71; isEnabled=true}; Password:
[PROTECTED]; Authenticated: true; Details: null; Granted Authorities: {DefaultAuthority:
authority=ROLE_USER}, o = invocation: method 'getUserInfoForUser', arguments [{DefaultUser:
username=mark; password=871deb9e1c3dd967da1d4f6d01999eb71a4eab71; isEnabled=true}]; target is of
class [edu.ucsc.whisper.core.manager.DefaultUserManager], config = [ROLE_USER, ROLE_ANONYMOUS,
AFTER_ACL_READ]>
2006-04-04 02:03:13,913 DEBUG [org.springframework.web.context.support.XmlWebApplicationContext] -
<Publishing event in context [WebApplicationContext for namespace 'xfire-servlet']:
org.acegisecurity.event.authorization.AuthorizedEvent[source=invocation: method
'getUserInfoForUser', arguments [{DefaultUser: username=mark;
password=871deb9e1c3dd967da1d4f6d01999eb71a4eab71; isEnabled=true}]; target is of class
[edu.ucsc.whisper.core.manager.DefaultUserManager]]>
2006-04-04 02:03:13,914 DEBUG [org.springframework.web.context.support.XmlWebApplicationContext] -
<Publishing event in context [Root WebApplicationContext]:
org.acegisecurity.event.authorization.AuthorizedEvent[source=invocation: method
'getUserInfoForUser', arguments [{DefaultUser: username=mark;
password=871deb9e1c3dd967da1d4f6d01999eb71a4eab71; isEnabled=true}]; target is of class
[edu.ucsc.whisper.core.manager.DefaultUserManager]]>
2006-04-04 02:03:13,914 DEBUG
[org.springframework.transaction.support.TransactionSynchronizationManager] - <Retrieved value
[org.springframework.orm.jdo.PersistenceManagerHolder@552f12] for key
[kodo.jdo.PersistenceManagerFactoryImpl@c2c9af] bound to thread [http-8443-Processor24]>
2006-04-04 02:03:13,915 DEBUG [kodo.Query] - <Executing query: [SELECT FROM
edu.ucsc.whisper.core.UserAccessControl
WHERE aclObjectId.domainObjectId==searchObjectId.domainObjectId
PARAMETERS edu.ucsc.whisper.core.DomainObjectIdentity searchObjectId] with
parameters: {searchObjectId=edu.ucsc.whisper.core.DefaultUserInfo:mark}>
2006-04-04 02:03:13,917 DEBUG [kodo.jdbc.JDBC] - <<t 11706420> connection pool: active=0, idle=1>
2006-04-04 02:03:13,917 DEBUG [kodo.jdbc.JDBC] - <<t 11706420, conn 15885558> checkout>
2006-04-04 02:03:13,917 DEBUG [kodo.jdbc.JDBC] - <<t 11706420> prepared statement cache: size=9,
max=50, requests=21, hits=12, created=9, redundant=0, overflow=0, leaked=0>
2006-04-04 02:03:13,919 DEBUG [kodo.jdbc.SQL] - <<t 11706420, conn 15885558> [2 ms] executing
prepstmnt 11249989 SELECT t0.accessControlId, t0.VERSN, t0.aclObjectId, t0.aclObjectParentId,
t0.permit, t1.userId, t1.TYP, t1.VERSN, t1.enabled, t1.password, t2.userInfoId, t2.TYPE, t2.VERSN,
t2.aboutText, t2.familyName, t2.firstName, t2.gender, t2.namePrefix, t2.nameSuffix, t2.otherNames,
t3.userId, t3.TYP, t3.VERSN, t3.enabled, t3.password, t3.USERINFO, t3.username, t1.username FROM
user_access_control t0 LEFT OUTER JOIN whisper_user t1 ON t0.userId = t1.userId LEFT OUTER JOIN
userinfo t2 ON t1.USERINFO = t2.userInfoId LEFT OUTER JOIN whisper_user t3 ON t2.userInfoId =
t3.USERINFO WHERE (t0.aclObjectId = ?) [params=(String) edu.ucsc.whisper.core.DefaultUserInfo:mark]
[reused=1]>
2006-04-04 02:03:13,920 DEBUG [kodo.jdbc.JDBC] - <<t 11706420, conn 15885558> return>
2006-04-04 02:03:13,921 DEBUG [kodo.jdbc.JDBC] - <<t 11706420, conn 15885558> [1 ms] close>
2006-04-04 02:03:13,921 DEBUG
[org.springframework.transaction.support.TransactionSynchronizationManager] - <Retrieved value
[org.springframework.orm.jdo.PersistenceManagerHolder@552f12] for key
[kodo.jdo.PersistenceManagerFactoryImpl@c2c9af] bound to thread [http-8443-Processor24]>
2006-04-04 02:03:13,921 DEBUG [kodo.Query] - <Executing query: [SELECT FROM
edu.ucsc.whisper.core.AuthorityAccessControl
WHERE aclObjectId.domainObjectId==searchObjectId.domainObjectId
PARAMETERS edu.ucsc.whisper.core.DomainObjectIdentity searchObjectId] with
parameters: {searchObjectId=edu.ucsc.whisper.core.DefaultUserInfo:mark}>
2006-04-04 02:03:13,923 DEBUG [kodo.jdbc.JDBC] - <<t 11706420> connection pool: active=0, idle=1>
2006-04-04 02:03:13,924 DEBUG [kodo.jdbc.JDBC] - <<t 11706420, conn 15885558> checkout>
2006-04-04 02:03:13,924 DEBUG [kodo.jdbc.JDBC] - <<t 11706420> prepared statement cache: size=9,
max=50, requests=22, hits=13, created=9, redundant=0, overflow=0, leaked=0>
2006-04-04 02:03:13,927 DEBUG [kodo.jdbc.SQL] - <<t 11706420, conn 15885558> [2 ms] executing
prepstmnt 4389286 SELECT t0.accessControlId, t0.VERSN, t0.aclObjectId, t0.aclObjectParentId,
t0.permit, t1.authorityId, t1.TYP, t1.VERSN, t1.authority FROM authority_access_control t0 LEFT
OUTER JOIN authorities t1 ON t0.authorityId = t1.authorityId WHERE (t0.aclObjectId = ?)
[params=(String) edu.ucsc.whisper.core.DefaultUserInfo:mark] [reused=1]>
2006-04-04 02:03:13,928 DEBUG [kodo.jdbc.JDBC] - <<t 11706420, conn 15885558> return>
2006-04-04 02:03:13,928 DEBUG [kodo.jdbc.JDBC] - <<t 11706420, conn 15885558> [0 ms] close>
2006-04-04 02:03:13,928 INFO [edu.ucsc.whisper.core.dao.JdoAclDao] - <found the controls:
[{AuthorityAccessControl: aclObjectId=edu.ucsc.whisper.core.DefaultUserInfo:mark;
aclObjectParentId=null; permit=READ_WRITE; recipient={DefaultAuthority: authority=ROLE_ADMIN}},
{UserAccessControl: aclObjectId=edu.ucsc.whisper.core.DefaultUserInfo:mark; aclObjectParentId=null;
permit=READ_WRITE; recipient={DefaultUser: username=mark;
password=871deb9e1c3dd967da1d4f6d01999eb71a4eab71; isEnabled=true}}]>
2006-04-04 02:03:13,928 INFO [edu.ucsc.whisper.service.DefaultUserService] - <Updating user info for
mark>
2006-04-04 02:03:13,929 INFO [edu.ucsc.whisper.service.DefaultUserService] - <existing user info =
{DefaultUserInfo: prefix=null; firstName=null; otherNames=null; familyName=null; suffix=null;
previousNames=(); gender=0; aboutText=null}>
2006-04-04 02:03:13,929 INFO [edu.ucsc.whisper.service.DefaultUserService] - <new user info =
{UserInfoData: prefix=Mr.; firstName=Mark; otherNames=David; familyName=Slater; suffix=null;
previousNames=(); gender=0; aboutText=blah blah blah}>
2006-04-04 02:03:13,930 DEBUG
[org.springframework.transaction.interceptor.RuleBasedTransactionAttribute] - <Applying rules to
determine whether transaction should rollback on <4|false|4.0.0EA4> kodo.util.InvalidStateException:
To perform writes on persistent data outside of a transaction, the "NontransactionalWrite" property
must be set on the Transaction.
FailedObject: edu.ucsc.whisper.core.DefaultUserInfo-2>
2006-04-04 02:03:13,930 DEBUG
[org.springframework.transaction.interceptor.RuleBasedTransactionAttribute] - <Winning rollback rule
is: null>
2006-04-04 02:03:13,930 DEBUG
[org.springframework.transaction.interceptor.RuleBasedTransactionAttribute] - <No relevant rollback
rule found: applying superclass default>
2006-04-04 02:03:13,934 DEBUG [org.springframework.transaction.interceptor.TransactionInterceptor] -
<Invoking rollback for transaction on edu.ucsc.whisper.service.UserService.setUserInformation due to
throwable [<4|false|4.0.0EA4> kodo.util.InvalidStateException: To perform writes on persistent data
outside of a transaction, the "NontransactionalWrite" property must be set on the Transaction.
FailedObject: edu.ucsc.whisper.core.DefaultUserInfo-2]>
2006-04-04 02:03:13,934 DEBUG [org.springframework.transaction.jta.JtaTransactionManager] - <mdslog
- AbstractPlatformTransactionManager begin rollback>
2006-04-04 02:03:13,934 DEBUG [org.springframework.transaction.jta.JtaTransactionManager] - <mdslog
- AbstractPlatformTransactionManager begin processRollback>
2006-04-04 02:03:13,934 DEBUG [org.springframework.transaction.jta.JtaTransactionManager] - <mdslog
- AbstractPlatformTransactionManager begin triggerBeforeCompletion>
2006-04-04 02:03:13,934 DEBUG [org.springframework.transaction.jta.JtaTransactionManager] -
<Triggering beforeCompletion synchronization>
2006-04-04 02:03:13,934 DEBUG [org.springframework.transaction.jta.JtaTransactionManager] - <mdslog
- AbstractPlatformTransactionManager - synchronization =
org.springframework.orm.jdo.PersistenceManagerFactoryUtils$PersistenceManagerSynchronization@ff0f8a>
2006-04-04 02:03:13,934 DEBUG
[org.springframework.transaction.support.TransactionSynchronizationManager] - <Removed value
[org.springframework.orm.jdo.PersistenceManagerHolder@552f12] for key
[kodo.jdo.PersistenceManagerFactoryImpl@c2c9af] from thread [http-8443-Processor24]>
2006-04-04 02:03:13,934 DEBUG [org.springframework.orm.jdo.PersistenceManagerFactoryUtils] -
<Persistence manager kodo.jdo.PersistenceManagerImpl@cc70c2, factory
kodo.jdo.PersistenceManagerFactoryImpl@c2c9af is transactional: false>
2006-04-04 02:03:13,935 DEBUG [org.springframework.orm.jdo.PersistenceManagerFactoryUtils] -
<Closing JDO PersistenceManager>
2006-04-04 02:03:13,935 DEBUG [org.springframework.orm.jdo.PersistenceManagerFactoryUtils] - <
persistence manager = kodo.jdo.PersistenceManagerImpl@cc70c2, factory =
kodo.jdo.PersistenceManagerFactoryImpl@c2c9af>
2006-04-04 02:03:13,935 DEBUG [org.springframework.transaction.jta.JtaTransactionManager] - <mdslog
- AbstractPlatformTransactionManager end triggerBeforeCompletion>
2006-04-04 02:03:13,935 DEBUG [org.springframework.transaction.jta.JtaTransactionManager] -
<Initiating transaction rollback> -
Redundant Joins being generated
We currently have a performance issue which is caused by unneccessary
joins executed when navigating across relations. We have two tables call
them tableA and tableB with a relationship between them on columnA.
This is a legacy database (25 years old) and does not have any primary
key or foreign key constraints. tableA is mapped to ClassA and tableB is
mapped to ClassB. If we have an instance of ClassA and navigate to ClassB,
I would expect a simple SELECT query to be executed, but instead a join is
included as well. Each table has 200,000 or so rows, so instead of taking
10s of ms, the query is taking more than a second each time. I have
executed the query I would expect and it does take 10ms, and the hardware
we have is fairly meaty. If there something we have configured incorrectly,
or is the absence of primary and foreign keys causing the issue?
The SQL I would expect is:
select t1.columnA, t1.columnB, t1.columnC from tableB t1 where t1.columnA
= '0123456789'
Instead we get:
select t1.columnA, t1.columnB, t1.columnC from tableA t0 inner join tableB
on t0.columnA = t1.columnB where t0.colu
mnA = '0123456789'
I do not see the need for the join as the value of columnA is known,
making the join redundant.
Here are the details (abbreviated):
Java Classes:
public class ClassA {
private String columnA;
private ClassB classB;
public class ClassB {
private String columnA;
// some other fields
private String columnB;
private String columnC;
SQL Tables:
create table tableA (columnA char(10))
create table tableB (columnA char(10), columnB char(10), column char(10))
package.jdo: We have to lie to the kodo about foreign keys or nothing
works.
<class name="ClassA" objectid-class="ClassAId">
<field name="columnA" primary-key="true"/>
</class>
<class name="ClassB" objectid-class="ClassBId">
<field name="columnA" primary-key="true"/>
</class>
package.mapping:
<class name="ClassA">
<jdbc-class-map type="base" table="tableA"/>
<jdbc-version-ind type="state-image"/>
<field name="classB">
<jdbc-field-map type="one-one" column.columnA="columnA"/>
</field>
<field name="columnA">
<jdbc-field-map type="value" column="columnA"/>
</field>
</class>
<class name="ClassB">
<jdbc-class-map type="base" table="tableB"/>
<jdbc-version-ind type="state-image"/>
<field name="classB">
<jdbc-field-map type="one-one" column.columnA="columnA"/>
</field>
<field name="columnA">
<jdbc-field-map type="value" column="columnA"/>
</field>
<field name="columnB">
<jdbc-field-map type="value" column="columnB"/>
</field>
<field name="columnC">
<jdbc-field-map type="value" column="columnC"/>
</field>
</class>OK,
My apologies it seems in the aim of simplifying the explanation of what is
occuring I missed some important pieces of information. It seems as though
the redundant joins are only occuring when do a mapping that contains a
constant value.
ie
<field name="classB">
<jdbc-field-map type="one-one" column.columnA="columnA"
column.columnB="XXXXXXXX" />
</field>
And looking at the Section 7.5 of the reference manual the SQL generated
has the redundant join also. Can someone explain why the join is necessary
in these circumstances. All the values of the join columns in tableB are
known, so why does tableA need to be referenced at all? -
Kodo 3.2.0b2 Now Available!
All,
Kodo 3.2.0b2 is now available. Get your copy while supplies last only from
SolarMetric at:
http://solarmetric.com/jdo/beta/3.2.0b2/
There are a number of exciting new features in 3.2.0b2, as well as a number
of fixes to bugs in the first beta:
a.. Many new JDO 2 preview features
b.. Improved eager fetching
c.. Query result grouping
d.. Query result ranges
e.. New built-in JDOQL methods
f.. Many other new features and bugfixes
g.. Intersystems Cach__ database support
h.. Many improvements to the Kodo workbench
You can find the release notes at:
http://www.solarmetric.com/Software/Documentation/3.2.0b2/docs/relnotes.html
Good luck, and enjoy!
-Greg
SolarMetric
www.solarmetric.comUsing a class indicator will typically be faster. We added the
subclass-join capability largely to support legacy schemas that don't
have an indicator.
-Patrick
Alex Roytman wrote:
How would you compare performance of fetching vertically mapped class
hierarchy using subclass-join indicator (outer joins) vs traditional fetch
based on class indicator? I often seen poor performance with outer joins
especially if you have several of them and some inner joins as well. In some
cases UNION ALL worked much better
"Greg Campbell" <[email protected]> wrote in message
news:ch2tfg$mp2$[email protected]..
All,
Kodo 3.2.0RC1 is now available. Feel free to download it at:
http://www.solarmetric.com/jdo/Evaluate/
There are a number of exciting new features in 3.2.0RC1, as well as a
number
of fixes to bugs found during the beta period:
* Many new JDO 2 preview features
* Single string JDOQL
* Named queries
* Optional managed inverses
* Improved eager fetching
* Many other new features and bugfixes
You can find the release notes at:
http://www.solarmetric.com/Software/Documentation/3.2.0RC1/docs/relnotes.html
As this is a release candidate, please report any issues that you find to
the Kodo
beta newsgroup (solarmetric.kodo.beta).
Good luck, and enjoy!
-Greg
SolarMetric
www.solarmetric.com -
Kodo 3.2.0RC1 Now Available
All,
Kodo 3.2.0RC1 is now available. Feel free to download it at:
http://www.solarmetric.com/jdo/Evaluate/
There are a number of exciting new features in 3.2.0RC1, as well as a number
of fixes to bugs found during the beta period:
* Many new JDO 2 preview features
* Single string JDOQL
* Named queries
* Optional managed inverses
* Improved eager fetching
* Many other new features and bugfixes
You can find the release notes at:
http://www.solarmetric.com/Software/Documentation/3.2.0RC1/docs/relnotes.html
As this is a release candidate, please report any issues that you find to
the Kodo
beta newsgroup (solarmetric.kodo.beta).
Good luck, and enjoy!
-Greg
SolarMetric
www.solarmetric.comUsing a class indicator will typically be faster. We added the
subclass-join capability largely to support legacy schemas that don't
have an indicator.
-Patrick
Alex Roytman wrote:
How would you compare performance of fetching vertically mapped class
hierarchy using subclass-join indicator (outer joins) vs traditional fetch
based on class indicator? I often seen poor performance with outer joins
especially if you have several of them and some inner joins as well. In some
cases UNION ALL worked much better
"Greg Campbell" <[email protected]> wrote in message
news:ch2tfg$mp2$[email protected]..
All,
Kodo 3.2.0RC1 is now available. Feel free to download it at:
http://www.solarmetric.com/jdo/Evaluate/
There are a number of exciting new features in 3.2.0RC1, as well as a
number
of fixes to bugs found during the beta period:
* Many new JDO 2 preview features
* Single string JDOQL
* Named queries
* Optional managed inverses
* Improved eager fetching
* Many other new features and bugfixes
You can find the release notes at:
http://www.solarmetric.com/Software/Documentation/3.2.0RC1/docs/relnotes.html
As this is a release candidate, please report any issues that you find to
the Kodo
beta newsgroup (solarmetric.kodo.beta).
Good luck, and enjoy!
-Greg
SolarMetric
www.solarmetric.com
Maybe you are looking for
-
Plug-in errors and dependency errors with a CAF app in DS in NW CE 7.1
I am learining to build CAF apps in Developer Studio in NW CE 7.1. Here are my steps and the errors I am getting: Open Developer Studio Switch to the CA perspective File->New->Project Choose Development Component under Development Infrastructure Pre
-
How can I get FF to always open all of my homepages?
I am using FF v.3.6.10 & XP with Service Pack 3. I am always conscious of installing the latest updates available for all of my programs. I use 4 homepages but occasionally when I open FF it only remembers my first homepage (which incidentally is htt
-
Hello members: we have a business scenario: SOAP to RFC sync an external system (ABC) sends documentrequest thru XI SOAP adapter and makes an RFC call to a BAPI and gets back the resposne to the ABC system.we are handling 4 mappings. 1. request msg t
-
Hi, I'm currently trying to get to know Java EE and thus playing around a little. But off course this means some trouble can happen along the road... I created an EJB called TitleCheckerBean with a local interface TitleCheckerLocal which I can use wi
-
Hi, I am having some trouble understanding packages. The following simple code to sort an integer array generates an error ("cannot find symbol")... import java.util.*; public class TestArraySort public static void main(String[] args)