Eager Fetching recursivity bug
I have two classes A and B.
A has two relations to B.
A.theB1 (A 1-1 to B)
A.theB2 (A 1-n to B)
B has two relation to A.
B.theA1 (B 1-n to A)
B.theA2 (B 1-n to A)
If I configure A.theB1 and A.theB2 with default-fetch-group="true".
And then I Use Eager Fetching multiple:everything works fine.
But if I also configure B.theA1 and B.theA2 with
default-fetch-group="true".
And then I Use Eager Fetching multiple
I get this Exception:
java.lang.StackOverflowError
at java.util.TreeMap.access$400(TreeMap.java:77)
at java.util.TreeMap$EntryIterator.nextEntry(TreeMap.java:1024)
at java.util.TreeMap$KeyIterator.next(TreeMap.java:1047)
at java.util.TreeMap.buildFromSorted(TreeMap.java:1588)
at java.util.TreeMap.buildFromSorted(TreeMap.java:1576)
at java.util.TreeMap.buildFromSorted(TreeMap.java:1534)
at java.util.TreeMap.addAllForTreeSet(TreeMap.java:1492)
at java.util.TreeSet.addAll(TreeSet.java:247)
at kodo.jdbc.sql.AbstractSelect$JoinSet.<init>(AbstractSelect.java:1021)
at kodo.jdbc.sql.AbstractSelect.and(AbstractSelect.java:719)
at kodo.jdbc.sql.AbstractSelect.getJoins(AbstractSelect.java:541)
at kodo.jdbc.sql.AbstractSelect.select(AbstractSelect.java:229)
at kodo.jdbc.sql.AbstractSelect.select(AbstractSelect.java:221)
at
kodo.jdbc.runtime.JDBCStoreManager.selectBaseMappings(JDBCStoreManager.java:874)
at
kodo.jdbc.runtime.JDBCStoreManager.selectMappings(JDBCStoreManager.java:835)
at kodo.jdbc.runtime.JDBCStoreManager.access$000(JDBCStoreManager.java:30)
at
kodo.jdbc.runtime.JDBCStoreManager$SelectImpl.selectInternal(JDBCStoreManager.java:1071)
at kodo.jdbc.sql.AbstractSelect.select(AbstractSelect.java:259)
at
kodo.jdbc.meta.OneToOneFieldMapping.select(OneToOneFieldMapping.java:452)
at
kodo.jdbc.runtime.JDBCStoreManager.selectBaseMappings(JDBCStoreManager.java:909)
at
kodo.jdbc.runtime.JDBCStoreManager.selectMappings(JDBCStoreManager.java:835)
at kodo.jdbc.runtime.JDBCStoreManager.access$000(JDBCStoreManager.java:30)
at
kodo.jdbc.runtime.JDBCStoreManager$SelectImpl.selectInternal(JDBCStoreManager.java:1071)
at kodo.jdbc.sql.AbstractSelect.select(AbstractSelect.java:259)
at
kodo.jdbc.meta.OneToOneFieldMapping.select(OneToOneFieldMapping.java:452)
at
kodo.jdbc.runtime.JDBCStoreManager.selectBaseMappings(JDBCStoreManager.java:909)
at
kodo.jdbc.runtime.JDBCStoreManager.selectMappings(JDBCStoreManager.java:835)
at kodo.jdbc.runtime.JDBCStoreManager.access$000(JDBCStoreManager.java:30)
at
kodo.jdbc.runtime.JDBCStoreManager$SelectImpl.selectInternal(JDBCStoreManager.java:1071)
at kodo.jdbc.sql.AbstractSelect.select(AbstractSelect.java:259)
at
kodo.jdbc.meta.ManyToManyFieldMapping.load(ManyToManyFieldMapping.java:350)
at kodo.jdbc.runtime.JDBCStoreManager.load(JDBCStoreManager.java:427)
at
kodo.runtime.DelegatingStoreManager.load(DelegatingStoreManager.java:141)
at
kodo.datacache.DataCacheStoreManager.load(DataCacheStoreManager.java:386)
at
kodo.runtime.DelegatingStoreManager.load(DelegatingStoreManager.java:141)
at kodo.runtime.ROPStoreManager.load(ROPStoreManager.java:82)
at kodo.runtime.StateManagerImpl.loadFields(StateManagerImpl.java:2274)
at kodo.runtime.StateManagerImpl.load(StateManagerImpl.java:139)
at
kodo.runtime.PersistenceManagerImpl.load(PersistenceManagerImpl.java:2408)
at
kodo.runtime.PersistenceManagerImpl.getObjectById(PersistenceManagerImpl.java:1244)
at
kodo.runtime.PersistenceManagerImpl.getObjectById(PersistenceManagerImpl.java:1175)
at kodo.jdbc.runtime.JDBCStoreManager.load(JDBCStoreManager.java:677)
at kodo.jdbc.meta.OneToOneFieldMapping.load(OneToOneFieldMapping.java:481)
at kodo.jdbc.runtime.JDBCStoreManager.load(JDBCStoreManager.java:731)
at kodo.jdbc.runtime.JDBCStoreManager.load(JDBCStoreManager.java:720)
at kodo.jdbc.runtime.JDBCStoreManager.load(JDBCStoreManager.java:720)
at
kodo.jdbc.runtime.JDBCStoreManager.initialize(JDBCStoreManager.java:338)
at
kodo.runtime.DelegatingStoreManager.initialize(DelegatingStoreManager.java:134)
at
kodo.datacache.DataCacheStoreManager.initialize(DataCacheStoreManager.java:340)
at
kodo.runtime.DelegatingStoreManager.initialize(DelegatingStoreManager.java:134)
at kodo.runtime.ROPStoreManager.initialize(ROPStoreManager.java:57)
at
kodo.runtime.PersistenceManagerImpl.getObjectById(PersistenceManagerImpl.java:1240)
at
kodo.runtime.PersistenceManagerImpl.getObjectById(PersistenceManagerImpl.java:1175)
at kodo.jdbc.runtime.JDBCStoreManager.load(JDBCStoreManager.java:677)
at kodo.jdbc.meta.OneToOneFieldMapping.load(OneToOneFieldMapping.java:481)
at kodo.jdbc.runtime.JDBCStoreManager.load(JDBCStoreManager.java:731)
at
kodo.jdbc.runtime.JDBCStoreManager.initialize(JDBCStoreManager.java:338)
at
kodo.runtime.DelegatingStoreManager.initialize(DelegatingStoreManager.java:134)
at
kodo.datacache.DataCacheStoreManager.initialize(DataCacheStoreManager.java:340)
at
kodo.runtime.DelegatingStoreManager.initialize(DelegatingStoreManager.java:134)
at kodo.runtime.ROPStoreManager.initialize(ROPStoreManager.java:57)
I have test every combination and what I see ,is that the Exception comes
because "Eager Fetching" process works recursively.
I remmember the same problem with Top Link Batch Reading.
I don't know if this could help: but I see two solutions.
1) explicity option to work recursively or not.
2) limitate depth level of recursivity.
This is the configuration file:
javax.jdo.PersistenceManagerFactoryClass:
kodo.jdbc.runtime.JDBCPersistenceManagerFactory
javax.jdo.option.ConnectionDriverName: com.jnetdirect.jsql.JSQLDriver
javax.jdo.option.ConnectionUserName: sa
javax.jdo.option.ConnectionPassword:
javax.jdo.option.ConnectionURL:
jdbc:JSQLConnect://agarcia/database=kodo3/SelectMethod=cursor
javax.jdo.option.Optimistic: true
javax.jdo.option.RetainValues: true
javax.jdo.option.NontransactionalRead: false
kodo.ConnectionFactoryProperties: MaxCachedStatements=0
kodo.DataCacheClass: kodo.datacache.CacheImpl
kodo.DataCacheProperties: CacheSize=1000000
kodo.PersistenceManagerClass: kodo.runtime.PersistenceManagerImpl
kodo.QueryCacheProperties: CacheSize=10000
kodo.RemoteCommitProviderClass: kodo.event.SingleJVMRemoteCommitProvider
kodo.jdbc.DBDictionaryClass=kodo.jdbc.sql.SQLServerDictionary
kodo.jdbc.TransactionIsolation=
javax.jdo.option.Multithreaded: true
## Transaction ###
kodo.TransactionMode: managed
kodo.ManagedRuntimeClass: kodo.ee.JNDIManagedRuntime
kodo.ManagedRuntimeProperties:
TransactionManagerName=java:/TransactionManager
#kodo.jdbc.MappingFactoryClass: kodo.jdbc.meta.MetaDataMappingFactory
kodo.jdbc.DBDictionaryProperties: BatchLimit=0 JoinSyntax=sql92
kodo.EagerFetchMode: multiple
kodo.FetchBatchSize: 10000
kodo.FetchThreshold: -1
Oh boy. Oops.
Thanks for the report.
-Patrick
On Fri, 01 Aug 2003 16:57:52 +0000, oscar wrote:
>
I have two classes A and B.
A has two relations to B.
A.theB1 (A 1-1 to B)
A.theB2 (A 1-n to B)
B has two relation to A.
B.theA1 (B 1-n to A)
B.theA2 (B 1-n to A)
If I configure A.theB1 and A.theB2 with default-fetch-group="true".
And then I Use Eager Fetching multiple:everything works fine.
But if I also configure B.theA1 and B.theA2 with
default-fetch-group="true".
And then I Use Eager Fetching multiple
I get this Exception:
java.lang.StackOverflowError
at java.util.TreeMap.access$400(TreeMap.java:77)
at java.util.TreeMap$EntryIterator.nextEntry(TreeMap.java:1024)
at java.util.TreeMap$KeyIterator.next(TreeMap.java:1047)
at java.util.TreeMap.buildFromSorted(TreeMap.java:1588)
at java.util.TreeMap.buildFromSorted(TreeMap.java:1576)
at java.util.TreeMap.buildFromSorted(TreeMap.java:1534)
at java.util.TreeMap.addAllForTreeSet(TreeMap.java:1492)
at java.util.TreeSet.addAll(TreeSet.java:247)
at kodo.jdbc.sql.AbstractSelect$JoinSet.<init>(AbstractSelect.java:1021)
at kodo.jdbc.sql.AbstractSelect.and(AbstractSelect.java:719)
at kodo.jdbc.sql.AbstractSelect.getJoins(AbstractSelect.java:541)
at kodo.jdbc.sql.AbstractSelect.select(AbstractSelect.java:229)
at kodo.jdbc.sql.AbstractSelect.select(AbstractSelect.java:221)
at
kodo.jdbc.runtime.JDBCStoreManager.selectBaseMappings(JDBCStoreManager.java:874)
at
kodo.jdbc.runtime.JDBCStoreManager.selectMappings(JDBCStoreManager.java:835)
at kodo.jdbc.runtime.JDBCStoreManager.access$000(JDBCStoreManager.java:30)
at
kodo.jdbc.runtime.JDBCStoreManager$SelectImpl.selectInternal(JDBCStoreManager.java:1071)
at kodo.jdbc.sql.AbstractSelect.select(AbstractSelect.java:259)
at
kodo.jdbc.meta.OneToOneFieldMapping.select(OneToOneFieldMapping.java:452)
at
kodo.jdbc.runtime.JDBCStoreManager.selectBaseMappings(JDBCStoreManager.java:909)
at
kodo.jdbc.runtime.JDBCStoreManager.selectMappings(JDBCStoreManager.java:835)
at kodo.jdbc.runtime.JDBCStoreManager.access$000(JDBCStoreManager.java:30)
at
kodo.jdbc.runtime.JDBCStoreManager$SelectImpl.selectInternal(JDBCStoreManager.java:1071)
at kodo.jdbc.sql.AbstractSelect.select(AbstractSelect.java:259)
at
kodo.jdbc.meta.OneToOneFieldMapping.select(OneToOneFieldMapping.java:452)
at
kodo.jdbc.runtime.JDBCStoreManager.selectBaseMappings(JDBCStoreManager.java:909)
at
kodo.jdbc.runtime.JDBCStoreManager.selectMappings(JDBCStoreManager.java:835)
at kodo.jdbc.runtime.JDBCStoreManager.access$000(JDBCStoreManager.java:30)
at
kodo.jdbc.runtime.JDBCStoreManager$SelectImpl.selectInternal(JDBCStoreManager.java:1071)
at kodo.jdbc.sql.AbstractSelect.select(AbstractSelect.java:259)
at
kodo.jdbc.meta.ManyToManyFieldMapping.load(ManyToManyFieldMapping.java:350)
at kodo.jdbc.runtime.JDBCStoreManager.load(JDBCStoreManager.java:427)
at
kodo.runtime.DelegatingStoreManager.load(DelegatingStoreManager.java:141)
at
kodo.datacache.DataCacheStoreManager.load(DataCacheStoreManager.java:386)
at
kodo.runtime.DelegatingStoreManager.load(DelegatingStoreManager.java:141)
at kodo.runtime.ROPStoreManager.load(ROPStoreManager.java:82)
at kodo.runtime.StateManagerImpl.loadFields(StateManagerImpl.java:2274)
at kodo.runtime.StateManagerImpl.load(StateManagerImpl.java:139)
at
kodo.runtime.PersistenceManagerImpl.load(PersistenceManagerImpl.java:2408)
at
kodo.runtime.PersistenceManagerImpl.getObjectById(PersistenceManagerImpl.java:1244)
at
kodo.runtime.PersistenceManagerImpl.getObjectById(PersistenceManagerImpl.java:1175)
at kodo.jdbc.runtime.JDBCStoreManager.load(JDBCStoreManager.java:677)
at kodo.jdbc.meta.OneToOneFieldMapping.load(OneToOneFieldMapping.java:481)
at kodo.jdbc.runtime.JDBCStoreManager.load(JDBCStoreManager.java:731)
at kodo.jdbc.runtime.JDBCStoreManager.load(JDBCStoreManager.java:720)
at kodo.jdbc.runtime.JDBCStoreManager.load(JDBCStoreManager.java:720)
at
kodo.jdbc.runtime.JDBCStoreManager.initialize(JDBCStoreManager.java:338)
at
kodo.runtime.DelegatingStoreManager.initialize(DelegatingStoreManager.java:134)
at
kodo.datacache.DataCacheStoreManager.initialize(DataCacheStoreManager.java:340)
at
kodo.runtime.DelegatingStoreManager.initialize(DelegatingStoreManager.java:134)
at kodo.runtime.ROPStoreManager.initialize(ROPStoreManager.java:57)
at
kodo.runtime.PersistenceManagerImpl.getObjectById(PersistenceManagerImpl.java:1240)
at
kodo.runtime.PersistenceManagerImpl.getObjectById(PersistenceManagerImpl.java:1175)
at kodo.jdbc.runtime.JDBCStoreManager.load(JDBCStoreManager.java:677)
at kodo.jdbc.meta.OneToOneFieldMapping.load(OneToOneFieldMapping.java:481)
at kodo.jdbc.runtime.JDBCStoreManager.load(JDBCStoreManager.java:731)
at
kodo.jdbc.runtime.JDBCStoreManager.initialize(JDBCStoreManager.java:338)
at
kodo.runtime.DelegatingStoreManager.initialize(DelegatingStoreManager.java:134)
at
kodo.datacache.DataCacheStoreManager.initialize(DataCacheStoreManager.java:340)
at
kodo.runtime.DelegatingStoreManager.initialize(DelegatingStoreManager.java:134)
at kodo.runtime.ROPStoreManager.initialize(ROPStoreManager.java:57)
I have test every combination and what I see ,is that the Exception comes
because "Eager Fetching" process works recursively.
I remmember the same problem with Top Link Batch Reading.
I don't know if this could help: but I see two solutions.
1) explicity option to work recursively or not.
2) limitate depth level of recursivity.
This is the configuration file:
javax.jdo.PersistenceManagerFactoryClass:
kodo.jdbc.runtime.JDBCPersistenceManagerFactory
javax.jdo.option.ConnectionDriverName: com.jnetdirect.jsql.JSQLDriver
javax.jdo.option.ConnectionUserName: sa
javax.jdo.option.ConnectionPassword:
javax.jdo.option.ConnectionURL:
jdbc:JSQLConnect://agarcia/database=kodo3/SelectMethod=cursor
javax.jdo.option.Optimistic: true
javax.jdo.option.RetainValues: true
javax.jdo.option.NontransactionalRead: false
kodo.ConnectionFactoryProperties: MaxCachedStatements=0
kodo.DataCacheClass: kodo.datacache.CacheImpl
kodo.DataCacheProperties: CacheSize=1000000
kodo.PersistenceManagerClass: kodo.runtime.PersistenceManagerImpl
kodo.QueryCacheProperties: CacheSize=10000
kodo.RemoteCommitProviderClass: kodo.event.SingleJVMRemoteCommitProvider
kodo.jdbc.DBDictionaryClass=kodo.jdbc.sql.SQLServerDictionary
kodo.jdbc.TransactionIsolation=
javax.jdo.option.Multithreaded: true
## Transaction ###
kodo.TransactionMode: managed
kodo.ManagedRuntimeClass: kodo.ee.JNDIManagedRuntime
kodo.ManagedRuntimeProperties:
TransactionManagerName=java:/TransactionManager
#kodo.jdbc.MappingFactoryClass: kodo.jdbc.meta.MetaDataMappingFactory
kodo.jdbc.DBDictionaryProperties: BatchLimit=0 JoinSyntax=sql92
kodo.EagerFetchMode: multiple
kodo.FetchBatchSize: 10000
kodo.FetchThreshold: -1--
Patrick Linskey
SolarMetric Inc.
Similar Messages
-
SQL Batch doesn't seem to work; How to eager-fetch related objects?
Hi,
I have two technical questions with Kodo.
1. SQL Batch doesn't seem to work. I have tried batch size of -1, 0, 1, 25.
But the performance from batch creating objects is not affected by batch
size.
kodo.jdbc.DBDictionary: BatchLimit=25
2. How to use custom fetch groups to eagerly fetch related persistable
objects? Example only showed attributes, not relationships.
Enviroment:
* Kodo 3.1.0 RC1
* Oracle 9i release 1.
Qingshan Luo
Senior Software Engineer
Open Harbor
1123 Industrial Road
San Carlos, CA 94070
Phone: 650-413-4251
Fax: 650-413-4298try poracle 10g driver. At least they fixed terrible CLOB bug may be batch
to. BTW 9.2.x has problem with batching with deferred constraints so be
careful
"Greg Campbell" <[email protected]> wrote in message
news:c3dmnu$rmj$[email protected]..
>
"Qingshan Luo" <[email protected]> wrote in message
news:c3dg7q$mdl$[email protected]..
Hi,
I have two technical questions with Kodo.
1. SQL Batch doesn't seem to work. I have tried batch size of -1, 0, 1,25.
But the performance from batch creating objects is not affected by batch
size.
kodo.jdbc.DBDictionary: BatchLimit=25You may be running into a bug in the Oracle 9.2 driver. That driverdoesn't
reliably give update counts when using batching and prepared statement
caching. By default, Kodo will turn off batching. You can manuallyenable
batching by setting the BatchLimit on your DBDictionary, as you've done.If
you do this, though, you may want to turn off prepared statement cachingby
setting MaxCachedStatements to 0 (see
http://www.solarmetric.com/Software/Documentation/3.1.0RC1/docs/ref_guide_dbsetup.html#ref_guide_dbsetup_builtin).
>
2. How to use custom fetch groups to eagerly fetch related persistable
objects? Example only showed attributes, not relationships.You can find information on setting up eager fetching of relations at
http://www.solarmetric.com/Software/Documentation/3.0.3/docs/ref_guide_
perfpack_eager.html
Basically, you'll need to add the relations to your fetch group, and
set the eager fetching mode.
Enviroment:
* Kodo 3.1.0 RC1
* Oracle 9i release 1.
Qingshan Luo
Senior Software Engineer
Open Harbor
1123 Industrial Road
San Carlos, CA 94070
Phone: 650-413-4251
Fax: 650-413-4298 -
BlazeDS - n:m relation with eager loading - recursion?
Hello to all!
I have a n:m relation and I do eager loading with Hibernate (and other relations with 1:n and n:m, but not displayed here):
@ManyToMany(fetch=FetchType.EAGER)
@JoinTable(name = "Group_User",
joinColumns = {@JoinColumn(name="group_id", referencedColumnName="id")},
inverseJoinColumns = {@JoinColumn(name="user_id", referencedColumnName="id")}
@Fetch(FetchMode.SELECT)
private List<User> users;
@ManyToMany(mappedBy="users", fetch=FetchType.EAGER)
@Fetch(FetchMode.SELECT)
private List<Group> groups;
So one user can have several groups and in one group can be several users.
So, but now I get all groups in Flex frontend and so I have also all users included, but the problem is, I get a kind of recursion here.
Debugging it and take a look at the groups, I see the users listed, and the user have groups, and these groups have users and so on and so on...
What shoud I do to solve this problem?
Thanks a lot in advance & Best Regards PHANTOMIASAbe, Any chance you could publish the answer on the newsgroup?
This was my support response:
I assume each child object is the same type as its parent? That is, you have a
class C with a
member of type Collection<C>?
In that case, consider what putting this member (let's call it M) in the
active fetch groups
does. When loading a C instance, M must be loaded. But if M is full of additional C
instances, then M must be loaded for all of those instances as well, since M is
in the active
fetch groups. And so forth. Thus, eager loading doesn't work very well when the
relation is
of the same type as the target object, because it causes a large recursive process.
SolarMetric has worked to make sure that JDO 2 fetch groups will allow for
specifications of
fetch depths and other advanced features. Until then, however, I'm afraid that
this is a
limitation of Kodo. I'm not sure how deep into your tree structure you want to
go, but you
might consider creating one or more Queries. For example, if you want children and
grandchildren, create one Query for all grandchildren, and one Query for all
children.
Execute both queries. Then going from a grandchild to its parent (I assume
there is a
relation from an object to its parent) won't cause any additional DB hits, since
the children
(the parents of the grandchildren) will already all be in cache. Similarly,
going from a child to
the root object might cause 1 additional DB hit if the root isn't already in
cache, but going
from subsequent children to the root will be satisfied from cache. Or if you
have multiple
roots, consider executing an additional Query for those roots. So in general,
you can fetch N
levels of the tree in N queries, and all relation traversals between those
levels will then be
satisfied from cache. -
I believe eager fetching can greatly benefit from more dynamic method then
predefined fetch groups.
Different queries pull different parts of object graph and only client using
object model knows what's needed for a particular query. Trying to fit
conflicting data needs into one set of fetch group is a challenge. While I
would retain this feature I would like to propose field based eager fetching
control. Which can also be used for Detached objects
Lets say we have PO with POLine collection and each POLine references
Product. If we want to eager fetch POs along with their lines and products
we could say something like
pm.getFetchConfiguration().addPath(com.peacetech.sales.PO.class, "lines");
pm.getFetchConfiguration().addPath(com.peacetech.sales.PO.class,
"lines/product");
or
pm.getFetchConfiguration().addPath(com.peacetech.sales.PO.class, pathList);
of course we would need
pm.getFetchConfiguration().removePath(com.peacetech.sales.PO.class,
"lines/product");
pm.getFetchConfiguration().addPath(com.peacetech.sales.PO.class); //remove
all for given class
This is just a crude example. In real life we should have few classes to
support the idea and main class GraphConfig or something so users can
configure, build and reuse those GraphConfig instances and use them for
various purposes like eager fetching and detaching without conflicts
I think it would be enormous help to uncouple so many conflicting issues
(fetch optimizations, optimistic locking field groups, detached graphs etc)
from one very limited concept of predefined fetch groupsMark,
I mentioned this possibility in on of my prior posts. It is not exactly what
I want (since it lack interclass relations which let you express hints for
deep graph rather than for a class and its fields) but close.
If you maintain your metadata files by hand it is too much effort but since
almost all my models and metadata are generated I can easily do (and undo)
it for each and every class/field and I will give it a try :-)
Alex
"Marc Prud'hommeaux" <[email protected]> wrote in message
news:[email protected]...
Alex-
Well, you could always simulate dynamic fetch groups by defining a
different custom fetch group for each field (provided your license has
the capability to use custom fetch groups). For simplicity, you could
name each fetch group to be "ClassName.fieldName".
That way, you could do something like this:
KodoQuery kq = (KodoQuery) pm.newQuery (MyClass.class, "someQuery");
kq.getFetchConfiguration ().addFetchGroup ("MyClass.fieldA");
kq.getFetchConfiguration ().addFetchGroup ("MyClass.fieldB");
kq.getFetchConfiguration ().addFetchGroup ("MyClass.fieldC");
kq.getFetchConfiguration ().addFetchGroup ("MyClass.fieldD");
Collection results = (Collection) kq.execute ();
It would them be pretty simple to make a static helper method that will
do thing like includeAllFieldsInFatchGroup() or
includeNoFieldsInFetchGroup().
In article <[email protected]>, Alex Roytman wrote:
David Tinker says multiple fetch group is the solution:
Hi Alex
You can create as many fetch groups as you like in the meta data (with
JDO
Genie anyway). I think it is much better to get tuning information likethis
out of the code. It should be added externally much like you add indexesto
database tables in response to query search requirements. I understandthat
sometimes you will need programatic control but mostly it is better notto
pollute the code.
JDO 2.0 is going to standardize the concept of a use-case. This willdelimit
business operations to the JDO implementation so it can applyappropriate
meta-data defined fetch groups or locking strategies. You will be ableto
use a vendor supplied tool to analyze the performance of yourapplication
and construct fetch groups for different use-cases (businessoperations). No
change to the code is necessary.
Here is an example:
CODE
pm.beginUseCase("com.peacetech.sales.displayOrder");
POClass o = (POClass)pm.getObjectById(oid, true);
.... other JDO code ....
pm.endUseCase();
The meta data for the use-case will specify the fetch group to use when
looking up the instance (and locking behaviour etc.). Other use-casescan
have different settings. Only the being/end calls are needed in the codeto
make this happen.
Note that this is a very long way from being finalized. I have just madeup
this example and how it works in JDO 2.0 is likely to be different.
Use-case support will show up in JDO Genie beta releases soon. Wealready
have powerful performance monitoring and analysis support in our GUI
Workbench and very flexible fetch groups.
Cheers
David
Here's my opinion
David,
Thank you for your response. Multiple fetch groups do give moreflexibility
(I do not believe Kodo supports it though) but does not alter myposition
>>
I do not want to pollute my metadata with tons of fetch groups creating
dependencies between my code and those fetch groups. JDOQL languagebeing
what it is already creates unavoidable dependency between field namesfilter
strings so I want to keep it the same way with other things which are
essentially references to persistent fields (Disconnected instancesdepth
control, Eagar fetching ....)
As for polluting my code. I want to assure you everything configurablewill
not be in my code but in JNDI or config files. As long as JDO givesclear
API for expressing graph path selection
Use case concept ties nicely with Graph Path selection concept. In factthis
GraphPaths class along with some additional options is your use case.
It is much easer for me to refactor and keep in sync field names and my
GraphPath than fetch groups.
Alex
"Abe White" <[email protected]> wrote in message
news:[email protected]...
I think the basic idea you've suggested is a good one. We'll certainly
consider it for a future release. The JDO 2 spec team is also
pondering
these problems...
Marc Prud'hommeaux [email protected]
SolarMetric Inc. http://www.solarmetric.com -
Eager fetching in multiple mode
Hi,
I have the following questions about eager fetching in multiple mode :
- for a to-many relation or collection field, what kind of join is used
for the separate select statement ?
- in my understanding, the gain in performance is due to the use of
batched select statements : is it correct or did I miss something here ?
Thanks in advance.
Regards.- for a to-many relation or collection field, what kind of join is used
for the separate select statement ?Inner. For a 2-many, there is no need for an outer join.
- in my understanding, the gain in performance is due to the use of
batched select statements : is it correct or did I miss something here ?The performance gain results from using a single SELECT per to-many
relation, rather than a SELECT per to-many relation, per object. For
example, let's say my Query matches 10 Project objects, and each Project
has 10 SubProjects, and each SubProject has some Workers. If I wanted
to retrieve all that data lazily, I would end up with 111 SELECTs:
1 SELECT for Projects matching the query
+ 10 SELECTs as I retrieve the SubProject relation from each of the 10
Project
+ 100 SELECTs as I retrieve the Workers relation from each of the 100
SubProjects (10 Projects with 10 SubProjects each).
With eager fetching, all the data is retrieved in 3 SELECTs instead:
1 SELECT for Projects matching the query
1 SELECT for SubProjects of the Projects matching the query
1 SELECT for Workers of the SubProjects of the Projects matching the query -
Hi,
I am using eager fetch in Kodo 3.1.3 but not sure if my configuration is
correct.
I have a Report object which contains a collection of Memos objects. It
is a 1-to-many relationship. After configure the kodo.properties and the
mapping file as following:
kodo.properties:
Add the following line
kodo.EagerFetchMode: multiple
kodo.Log: SQL=TRACE
In mapping jdo:
<class name="Report" objectid-class="ReportId">
<field name="memo" default-fetch-group="true">
<collection element-type="Memo"/>
</field>
<field name="policyId" primary-key="true"/>
</class>
After making those changes, running my application against the database
with say 100 reports, the SQL trace still showing 100 SQL statement rather
than 1 single SELECT as I understand, ie. select all 100 reports and all
associated memos in one visit to the db server.
Please correct me if I am worng. Thanks.
Cheers,
DienHi,
I am using eager fetch in Kodo 3.1.3 but not sure if my configuration is
correct.
I have a Report object which contains a collection of Memos objects. It
is a 1-to-many relationship. After configure the kodo.properties and the
mapping file as following:
kodo.properties:
Add the following line
kodo.EagerFetchMode: multiple
kodo.Log: SQL=TRACE
In mapping jdo:
<class name="Report" objectid-class="ReportId">
<field name="memo" default-fetch-group="true">
<collection element-type="Memo"/>
</field>
<field name="policyId" primary-key="true"/>
</class>
After making those changes, running my application against the database
with say 100 reports, the SQL trace still showing 100 SQL statement rather
than 1 single SELECT as I understand, ie. select all 100 reports and all
associated memos in one visit to the db server.
Please correct me if I am worng. Thanks.
Cheers,
Dien -
Eager Fetch Mode limit clarification
Hi,
I would like clarification of the following from the 3.3.4 docs
(kodo-jdo-3.3.4/docs/ref_guide_perfpack_eager.html):
"Once Kodo eager-joins into a class, it cannot issue any further eager
to-many joins or parallel selects from that class in the same query.
To-one joins, however, can recurse to any level."
Given the following class/table relationships:
X --> Y -->> Z
(where --> is one-to-one and -->> is one-to-many)
Does this mean that if I query X, Y can be eagerly fetched, but not Z?
This is certainly what we see - a join to fetch X and Y in one select
statement and then many one-off selects from Z for each Y.
Is there any way to load Z more efficiently? It would seem that once
Kodo has loaded the Y's that it knows all it needs to load the Z's with
one SQL select - Z would have a FK to Y, so "select ... from z where
y_id in (<kodo puts the loaded y ids here>)" would seem feasible,
especially given Kodo does this in other places.
Thanks,
RichardThanks Abe.
Abe White wrote:
X --> Y -->> Z
(where --> is one-to-one and -->> is one-to-many)
Does this mean that if I query X, Y can be eagerly fetched, but not Z?Yes, unfortunately.Our actual case also includes the following relationships: X -->> W -->>
V and strangely, they do seem to be be eagerly loaded when we query for
X. i.e. one query to load all Vs. How does this work given the above?
Is there any way to load Z more efficiently?Typical workarounds include querying for Y's instead of X's and using
the inverse relation from Y to X, or if there is no such relation,
performing 2 queries: one for Y's and one for X's.Are there any plans to support greater depth eager loadings in any
upcoming Kodo version?
Thanks again for your help,
Richard -
JDom Recursion Bugging me!!
Developers,
5 dukes for the correct anwer. I asked my manager and he couldnt figure this out so here goes. A simple recursion problem - or so you might think.
JDom only allows one level deep serach for a tag name - no problem - so i wrote a recursive method which looks for a tag no matter how many levels deep. Here is the code
public void getParentNode(Element element) {
if(element.getName().equals("content")){
System.out.println("RETURNED");
return parentElement ;
List content = element.getContent();
Iterator iterator = content.iterator();
while (iterator.hasNext()) {
Object o = iterator.next();
if (o instanceof Element) {
Element child = (Element) o;
return (getParentNode(child));
return null;
}I watched this in the debugger and it kept hitting the retrun null and also retrun the 'parentElement'. The tag is DEFINITEL in the xml file.
I have no idea what to do - I am thinking or ripping out all the JDom references and using Xceres DOM - but this will be a pain.
What have i done wrong?
Thanks.Instaed of iterating over the nodes select the node with an xpath expression.
import org.jdom.xpath.*;
File xmlDocument;
SAXBuilder saxBuilder=new SAXBuilder("org.apache.xerces.parsers.SAXParser");
org.jdom.Document jdomDocument=saxBuilder.build(xmlDocument);
org.jdom.Attribute contentNode=(XPath.selectSingleNode(jdomDocument,"//content"); -
SQL batch doesn't work; How to fetch related objects with fetch group?
I have two questions:
1. SQL Batch doesn't seem to work. I have tested some batch object creation
with BatchLimit set to -1, 0, 1, 25, 100. They all have similar
performance.
kodo.jdbc.DBDictionary: BatchLimit=25
2. How to use custom fetch group to fetch related objects? The example of
custom fetch group only show how to fetch different attributes in different
groups. I have a test cases where I would like to pre-fetch related objects
to save round trip.
Enviroments:
* Kodo 3.1.0 RC1
* Oracle 9i release 1
Thanks for any help!
Qingshan Luo
Senior Software Engineer
Open Harbor
1123 Industrial Road
San Carlos, CA 94070
Phone: 650-413-4251
Fax: 650-413-4298try poracle 10g driver. At least they fixed terrible CLOB bug may be batch
to. BTW 9.2.x has problem with batching with deferred constraints so be
careful
"Greg Campbell" <[email protected]> wrote in message
news:c3dmnu$rmj$[email protected]..
>
"Qingshan Luo" <[email protected]> wrote in message
news:c3dg7q$mdl$[email protected]..
Hi,
I have two technical questions with Kodo.
1. SQL Batch doesn't seem to work. I have tried batch size of -1, 0, 1,25.
But the performance from batch creating objects is not affected by batch
size.
kodo.jdbc.DBDictionary: BatchLimit=25You may be running into a bug in the Oracle 9.2 driver. That driverdoesn't
reliably give update counts when using batching and prepared statement
caching. By default, Kodo will turn off batching. You can manuallyenable
batching by setting the BatchLimit on your DBDictionary, as you've done.If
you do this, though, you may want to turn off prepared statement cachingby
setting MaxCachedStatements to 0 (see
http://www.solarmetric.com/Software/Documentation/3.1.0RC1/docs/ref_guide_dbsetup.html#ref_guide_dbsetup_builtin).
>
2. How to use custom fetch groups to eagerly fetch related persistable
objects? Example only showed attributes, not relationships.You can find information on setting up eager fetching of relations at
http://www.solarmetric.com/Software/Documentation/3.0.3/docs/ref_guide_
perfpack_eager.html
Basically, you'll need to add the relations to your fetch group, and
set the eager fetching mode.
Enviroment:
* Kodo 3.1.0 RC1
* Oracle 9i release 1.
Qingshan Luo
Senior Software Engineer
Open Harbor
1123 Industrial Road
San Carlos, CA 94070
Phone: 650-413-4251
Fax: 650-413-4298 -
ORA-01002/ Fetch out of sequence on lazy loading
Hello,
We are facing an oracle SQLException (ORA-01002: fetch out of sequence)
while we are trying to get a field (retrieved via lazy loading) from an
object that was retrieved using a kodoquery.
This error only occurs during performance testing under a heavy load.
(100 concurrent users). For each thread we get a new persistencemanager
from the factory. And we have put the multithreaded option to true.
Can anyone help us with this problem?
Thanks in advance,
Kind Regards,
Niels Soeffers
Caused by: java.sql.SQLException: ORA-01002: fetch out of sequence
at
oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:743)
at
oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:216)
at
oracle.jdbc.driver.T4CPreparedStatement.fetch(T4CPreparedStatement.java:1027)
at
oracle.jdbc.driver.OracleResultSetImpl.close_or_fetch_from_next(OracleResultSetImpl.java:291)
at
oracle.jdbc.driver.OracleResultSetImpl.next(OracleResultSetImpl.java:213)
at
com.solarmetric.jdbc.DelegatingResultSet.next(DelegatingResultSet.java:97)
at kodo.jdbc.sql.ResultSetResult.nextInternal(ResultSetResult.java:151)
at kodo.jdbc.sql.AbstractResult.next(AbstractResult.java:123)
at kodo.jdbc.sql.Select$SelectResult.next(Select.java:2236)
at
kodo.jdbc.meta.AbstractCollectionFieldMapping.load(AbstractCollectionFieldMapping.java:592)
at kodo.jdbc.runtime.JDBCStoreManager.load(JDBCStoreManager.java:521)
at
kodo.runtime.DelegatingStoreManager.load(DelegatingStoreManager.java:133)
at kodo.runtime.ROPStoreManager.load(ROPStoreManager.java:79)
at kodo.runtime.StateManagerImpl.loadFields(StateManagerImpl.java:3166)
at kodo.runtime.StateManagerImpl.loadField(StateManagerImpl.java:3265)
at kodo.runtime.StateManagerImpl.isLoaded(StateManagerImpl.java:1386)
at
com.ardatis.ventouris.domain.OntvangstReeks.jdoGetontvangstTransacties(OntvangstReeks.java)
at
com.ardatis.ventouris.domain.OntvangstReeks.getStatus(OntvangstReeks.java:72)
at
com.ardatis.ventouris.service.financien.transfer.FinancienTOAssembler.getOntvangstReeksBaseTO(FinancienTOAssembler.java:71)
at
com.ardatis.ventouris.service.financien.transfer.FinancienTOAssembler.getOntvangstReeksBaseTOs(FinancienTOAssembler.java:84)
at
com.ardatis.ventouris.service.financien.FinancienManagerImpl.getOntvangstReeksBaseTOs(FinancienManagerImpl.java:241)
at
com.ardatis.ventouris.service.financien.ejb.FinancienManagerBean.getOntvangstReeksBaseTOs(FinancienManagerBean.java:62)
at sun.reflect.GeneratedMethodAccessor181.invoke(Unknown Source)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at com.sun.enterprise.security.SecurityUtil$2.run(SecurityUtil.java:153)
at java.security.AccessController.doPrivileged(Native Method)
at
com.sun.enterprise.security.application.EJBSecurityManager.doAsPrivileged(EJBSecurityManager.java:950)
at com.sun.enterprise.security.SecurityUtil.invoke(SecurityUtil.java:158)
at
com.sun.ejb.containers.EJBObjectInvocationHandler.invoke(EJBObjectInvocationHandler.java:128)
at $Proxy31.getOntvangstReeksBaseTOs(Unknown Source)
at sun.reflect.GeneratedMethodAccessor155.invoke(Unknown Source)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at
com.sun.corba.ee.impl.presentation.rmi.ReflectiveTie._invoke(ReflectiveTie.java:123)We are using Oracle 10g and have tried multiple dirvers. (classes12.jar,
ojdbc14.jar)
Our kodo.properties ( actually the ra.xml we supply with the kodo.rar )
<connector>
<display-name>KodoJDO</display-name>
<description>Resource Adapter for integration of the Kodo Java Data
Objects (JDO) implementation with J2EE 1.3 compliant managed
environments</description>
<vendor-name>Solarmetric, Inc.</vendor-name>
<spec-version>1.0</spec-version>
<eis-type>jdo</eis-type>
<version>1.0</version>
<license>
<description>
See http://www.solarmetric.com for terms and license conditions.
</description>
<license-required>true</license-required>
</license>
<resourceadapter>
<managedconnectionfactory-class>kodo.jdbc.ee.JDBCManagedConnectionFactory</managedconnectionfactory-class>
<connectionfactory-interface>javax.resource.cci.ConnectionFactory</connectionfactory-interface>
<connectionfactory-impl-class>kodo.jdbc.ee.JDBCConnectionFactory</connectionfactory-impl-class>
<connection-interface>javax.resource.cci.Connection</connection-interface>
<connection-impl-class>kodo.runtime.PersistenceManagerImpl</connection-impl-class>
<transaction-support>XATransaction</transaction-support>
<config-property>
<description>A comma-separated list of query aggregate listeners
to add to the default list of extensions. Each listener must implement
the kodo.jdbc.query.JDBCAggregateListener interface.</description>
<config-property-name>AggregateListeners</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value></config-property-value>
</config-property>
<config-property>
<description>The kodo.jdbc.meta.ClassIndicator to use by default
for new mappings. The class indicator is responsible for tracking the
concrete class or subclass implemented by the object stored in each row of
a table.</description>
<config-property-name>ClassIndicator</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>in-class-name</config-property-value>
</config-property>
<config-property>
<description>The kodo.util.ClassResolver implementation that
should be used for JDO class resolution. Defaults to a JDO spec-compliant
resolver.</description>
<config-property-name>ClassResolver</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>spec</config-property-value>
</config-property>
<config-property>
<description>Details about various compatibiity levels for the
current environment.</description>
<config-property-name>Compatibility</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>true</config-property-value>
</config-property>
<config-property>
<description>The class name of either the JDBC java.sql.Driver, or
an instance of a javax.sql.DataSource to use to connect to the non-XA data
source.</description>
<config-property-name>Connection2DriverName</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value></config-property-value>
</config-property>
<config-property>
<description>The password for the user specified in
Connection2UserName</description>
<config-property-name>Connection2Password</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value></config-property-value>
</config-property>
<config-property>
<description>A comma-separated list of properties to be passed to
the non-XA JDBC Driver when obtaining a Connection. Properties are of the
form "key=value". If the given JDBC Driver class is a DataSource, these
properties will be used to configure the bean properties of the
DataSource. </description>
<config-property-name>Connection2Properties</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value></config-property-value>
</config-property>
<config-property>
<description>The URL for the non-XA data source.</description>
<config-property-name>Connection2URL</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value></config-property-value>
</config-property>
<config-property>
<description>The username for the connection listed in
Connection2URL.</description>
<config-property-name>Connection2UserName</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value></config-property-value>
</config-property>
<config-property>
<description>A comma-separated list of
com.solarmetric.jdbc.ConnectionDecorator implementations to install on all
connection pools.</description>
<config-property-name>ConnectionDecorators</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value></config-property-value>
</config-property>
<config-property>
<description>The class name of either the JDBC java.sql.Driver, or
an instance of a javax.sql.DataSource to use to connect to the data
source.</description>
<config-property-name>ConnectionDriverName</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value></config-property-value>
</config-property>
<config-property>
<description>The JNDI name of the connection factory to use for
finding non-XA connections. If specified, this is the connection that
will be used for obtaining sequence numbers.</description>
<config-property-name>ConnectionFactory2Name</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>jdbc/VentourisNonXA</config-property-value>
</config-property>
<config-property>
<description>A comma-separated list of properties used to
configure the javax.sql.DataSource used as the non-XA ConnectionFactory.
Each property should be of the form "key=value", where "key" is the name
of some bean-like property of the data source.</description>
<config-property-name>ConnectionFactory2Properties</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value></config-property-value>
</config-property>
<config-property>
<description>The JNDI name of the connection factory to use for
obtaining connections.</description>
<config-property-name>ConnectionFactoryName</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>jdbc/Ventouris</config-property-value>
</config-property>
<config-property>
<description>A comma-separated list of properties used to
configure the javax.sql.DataSource used as the ConnectionFactory. Each
property should be of the form "key=value", where "key" is the name of
some bean-like property of the data source.</description>
<config-property-name>ConnectionFactoryProperties</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value></config-property-value>
</config-property>
<config-property>
<description>The password for the user specified in
ConnectionUserName</description>
<config-property-name>ConnectionPassword</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value></config-property-value>
</config-property>
<config-property>
<description>A comma-separated list of properties to be passed to
the JDBC Driver when obtaining a Connection. Properties are of the form
"key=value". If the given JDBC Driver class is a DataSource, these
properties will be used to configure the bean properties of the
DataSource. </description>
<config-property-name>ConnectionProperties</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value></config-property-value>
</config-property>
<config-property>
<description>This property dictates when PersistenceManagers will
retain and release data store connections. Available options are
"on-demand" for retaining a connection only during pessimistic
transactions and data store operations, "transaction" for retaining a
connection for the life of each transaction, or "persistence-manager" to
indicate that a persistence manager should retain and reuse a single
connection for its entire lifespan.</description>
<config-property-name>ConnectionRetainMode</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>transaction</config-property-value>
</config-property>
<config-property>
<description>The URL for the data source.</description>
<config-property-name>ConnectionURL</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value></config-property-value>
</config-property>
<config-property>
<description>The username for the connection listed in
ConnectionURL.</description>
<config-property-name>ConnectionUserName</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value></config-property-value>
</config-property>
<config-property>
<description>Set to true if you''d like Kodo to copy all object
ids before returning them to your code. If you do not plan on modifying
identity objects, you can set this property to false to avoid the copying
overhead.</description>
<config-property-name>CopyObjectIds</config-property-name>
<config-property-type>java.lang.Boolean</config-property-type>
<config-property-value>false</config-property-value>
</config-property>
<config-property>
<description>Plugin used to cache data loaded from the data store.
Must implement kodo.datacache.DataCache.</description>
<config-property-name>DataCache</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value></config-property-value>
</config-property>
<config-property>
<description>The number of milliseconds that data in the data
cache is valid for. A value of 0 or less means that by default, cached
data does not time out.</description>
<config-property-name>DataCacheTimeout</config-property-name>
<config-property-type>java.lang.Integer</config-property-type>
<config-property-value>-1</config-property-value>
</config-property>
<config-property>
<description>The type of data source in use. Available options
are "local" for a standard data source under Kodo''s control, or
"enlisted" for a data source managed by an application server and
automatically enlisted in global transactions.</description>
<config-property-name>DataSourceMode</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>enlisted</config-property-value>
</config-property>
<config-property>
<description>The kodo.jdbc.sql.DBDictionary to use for database
interaction. This is auto-detected based on the setting of
javax.jdo.option.ConnectionURL, so you need only set this to override the
default with your own custom dictionary or if you are using an
unrecognized driver.</description>
<config-property-name>DBDictionary</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value></config-property-value>
</config-property>
<config-property>
<description>Whether to dynamically create custom structs to hold
and transfer persistent state in the Kodo data cache and remote
persistence manager frameworks. Dynamic structs can reduce data cache
memory consumption, reduce the amount of data serialized back and forth
under remote persistence managers, and improve the overall performance of
these systems. However, they increase application warm-up time while the
custom classes are generated and loaded into the JVM. Set to true to
enable dynamic data structs.</description>
<config-property-name>DynamicDataStructs</config-property-name>
<config-property-type>java.lang.Boolean</config-property-type>
<config-property-value>false</config-property-value>
</config-property>
<config-property>
<description>Specifies the default eager fetch mode to use.
Either "none" to never eagerly-load relations, "join" for selecting 1-1
relations along with the target object using inner or outer joins, or
"parallel" for selecting 1-1 relations via joins, and collections
(including to-many relations) along with the target object using separate
select statements executed in parallel.</description>
<config-property-name>EagerFetchMode</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>parallel</config-property-value>
</config-property>
<config-property>
<description>The number of rows that will be pre-fetched when an
element in a Query result is accessed. Use -1 to pre-fetch all
results.</description>
<config-property-name>FetchBatchSize</config-property-name>
<config-property-type>java.lang.Integer</config-property-type>
<config-property-value>-1</config-property-value>
</config-property>
<config-property>
<description>The name of the JDBC fetch direction to use.
Standard values are "forward", "reverse", and "unknown".</description>
<config-property-name>FetchDirection</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>forward</config-property-value>
</config-property>
<config-property>
<description>A comma-separated list of fetch group names that
PersistenceManagers will load by default when loading data from the data
store.</description>
<config-property-name>FetchGroups</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value></config-property-value>
</config-property>
<config-property>
<description>A comma-separated list of query filter listeners to
add to the default list of extensions. Each listener must implement the
kodo.jdbc.query.JDBCFilterListener interface.</description>
<config-property-name>FilterListeners</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value></config-property-value>
</config-property>
<config-property>
<description>Whether or not Kodo should automatically flush
modifications to the data store before executing queries.</description>
<config-property-name>FlushBeforeQueries</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>with-connection</config-property-value>
</config-property>
<config-property>
<description>If true, Kodo will order all SQL inserts, updates,
and deletes to meet your schema''s foreign key constraints. Defaults to
false.</description>
<config-property-name>ForeignKeyConstraints</config-property-name>
<config-property-type>java.lang.Boolean</config-property-type>
<config-property-value>false</config-property-value>
</config-property>
<config-property>
<description>If false, then the JDO implementation must consider
modifications, deletions, and additions in the PersistenceManager
transaction cache when executing a query inside a transaction. Else, the
implementation is free to ignore the cache and execute the query directly
against the data store.</description>
<config-property-name>IgnoreCache</config-property-name>
<config-property-type>java.lang.Boolean</config-property-type>
<config-property-value>true</config-property-value>
</config-property>
<config-property>
<description>Plugin used to manage inverse relations during flush.
Set to true to use the default inverse manager. Custom inverse managers
must extend kodo.runtime.InverseManager.</description>
<config-property-name>InverseManager</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>false</config-property-value>
</config-property>
<config-property>
<description>A comma-separated list of
com.solarmetric.jdbc.JDBCListener implementations to install on all
connection pools.</description>
<config-property-name>JDBCListeners</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value></config-property-value>
</config-property>
<config-property>
<description>The license key provided to you by SolarMetric. Keys
are available at www.solarmetric.com</description>
<config-property-name>LicenseKey</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value><KEY-REMOVED></config-property-value>
</config-property>
<config-property>
<description>Plugin used to handle acquiring locks on persistent
instances. Must implement kodo.runtime.LockManager.</description>
<config-property-name>LockManager</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>pessimistic</config-property-value>
</config-property>
<config-property>
<description>The number of milliseconds to wait for an object lock
before throwing an exception, or -1 for no limit.</description>
<config-property-name>LockTimeout</config-property-name>
<config-property-type>java.lang.Integer</config-property-type>
<config-property-value>-1</config-property-value>
</config-property>
<config-property>
<description>LogFactory and configuration for Kodo''s logging
needs.</description>
<config-property-name>Log</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>kodo(DefaultLevel=WARN, Tool=WARN,
Runtime=WARN, SQL=WARN)</config-property-value>
</config-property>
<config-property>
<description>The mode to use for calculating the size of large
result sets. Legal values are "unknown", "last", and "query".</description>
<config-property-name>LRSSize</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>query</config-property-value>
</config-property>
<config-property>
<description>Plugin used to integrate with an external transaction
manager. Must implement kodo.runtime.ManagedRuntime.</description>
<config-property-name>ManagedRuntime</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>auto</config-property-value>
</config-property>
<config-property>
<description>Plugin used to configure management and profiling
capabilities.</description>
<config-property-name>ManagementConfiguration</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>none</config-property-value>
</config-property>
<config-property>
<description>The kodo.jdbc.meta.MappingFactory that will provide
the object-relational mapping information needed to map each persistent
class to the database.</description>
<config-property-name>MappingFactory</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>file</config-property-value>
</config-property>
<config-property>
<description>Plugin used to create metadata about persistent
types. Must implement kodo.meta.MetaDataLoader</description>
<config-property-name>MetaDataLoader</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>jdo</config-property-value>
</config-property>
<config-property>
<description>If true, then the application plans to have multiple
threads simultaneously accessing a single PersistenceManager, so measures
must be taken to ensure that the implementation is thread-safe. Otherwise,
the implementation need not address thread safety.</description>
<config-property-name>Multithreaded</config-property-name>
<config-property-type>java.lang.Boolean</config-property-type>
<config-property-value>true</config-property-value>
</config-property>
<config-property>
<description>If true, then it is possible to read persistent data
outside the context of a transaction. Otherwise, a transaction must be in
progress in order read data.</description>
<config-property-name>NontransactionalRead</config-property-name>
<config-property-type>java.lang.Boolean</config-property-type>
<config-property-value>true</config-property-value>
</config-property>
<config-property>
<description>If true, then it is possible to write to fields of a
persistent-nontransactional object when a transaction is not in progress.
If false, such a write will result in a JDOUserException.</description>
<config-property-name>NontransactionalWrite</config-property-name>
<config-property-type>java.lang.Boolean</config-property-type>
<config-property-value>false</config-property-value>
</config-property>
<config-property>
<description>Determines the persistence manager's behavior in
calls to getObjectById with a validate parameter of false. Use "check" to
check that a database record exists for the object and load its fetch
group fields. Use "hollow" to return a hollow instance.</description>
<config-property-name>ObjectLookupMode</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>check</config-property-value>
</config-property>
<config-property>
<description>Selects between optimistic and pessimistic (data
store) transactional modes.</description>
<config-property-name>Optimistic</config-property-name>
<config-property-type>java.lang.Boolean</config-property-type>
<config-property-value>true</config-property-value>
</config-property>
<config-property>
<description>Action to take when Kodo discovers an orphaned key in
the database. May be a custom action implementing
kodo.event.OrphanedKeyAction.</description>
<config-property-name>OrphanedKeyAction</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>log</config-property-value>
</config-property>
<config-property>
<description>The name of the concrete implementation of
javax.jdo.PersistenceManagerFactory that
javax.jdo.JDOHelper.getPersistenceManagerFactory () should create. For
Kodo JDO, this should be kodo.jdbc.runtime.JDBCPersistenceManagerFactory
or a custom extension of this type.</description>
<config-property-name>PersistenceManagerFactoryClass</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>kodo.jdbc.runtime.JDBCPersistenceManagerFactory</config-property-value>
</config-property>
<config-property>
<description>Persistence manager plugin and properties. If you
use a custom class, it must extend
kodo.runtime.PersistenceManagerImpl.</description>
<config-property-name>PersistenceManagerImpl</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>default</config-property-value>
</config-property>
<config-property>
<description>Configure this persistence manager factory to service
remote persistence managers.</description>
<config-property-name>PersistenceManagerServer</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>false</config-property-value>
</config-property>
<config-property>
<description>A comma-separated list of the class names of all
persistent classes to register whenever a persistence manager is
obtained.</description>
<config-property-name>PersistentClasses</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>com.ardatis.ventouris.domain.KwartaalVerhoging,
com.ardatis.ventouris.domain.Land, com.ardatis.ventouris.domain.Gemeente,
com.ardatis.ventouris.domain.Adres,
com.ardatis.ventouris.domain.ContactGegeven,
com.ardatis.ventouris.domain.AdresContactGegeven,
com.ardatis.ventouris.common.type.AdresType,
com.ardatis.ventouris.domain.OntvangstTransactie,
com.ardatis.ventouris.domain.OntvangstReeks,
com.ardatis.ventouris.domain.Ontvangst,
com.ardatis.ventouris.domain.Inkomen,
com.ardatis.ventouris.domain.loopbaan.LoopbaanPeriode,
com.ardatis.ventouris.common.type.InkomenSoort,
com.ardatis.ventouris.common.type.INSZ,
com.ardatis.ventouris.domain.Aangeslotene,
com.ardatis.ventouris.domain.NatuurlijkePersoon,
com.ardatis.ventouris.domain.Persoon, com.ardatis.ventouris.domain.Rol,
com.ardatis.ventouris.domain.Dossier,
com.ardatis.ventouris.common.type.Geslacht,
com.ardatis.ventouris.common.type.Taal,
com.ardatis.ventouris.common.type.Nationaliteit,
com.ardatis.ventouris.common.type.KostType,
com.ardatis.ventouris.domain.Verhoging,
com.ardatis.ventouris.domain.Aanvraag,
com.ardatis.ventouris.domain.AanvraagAansluitingSS,
com.ardatis.ventouris.domain.AanvraagToestand,
com.ardatis.ventouris.common.type.AanvraagToestandType,
com.ardatis.ventouris.domain.Factuur,
com.ardatis.ventouris.domain.TaakType, com.ardatis.ventouris.domain.Taak,
com.ardatis.ventouris.domain.BijdrageBerekening,
com.ardatis.ventouris.domain.calculationparameters.HerwaarderingsIndex,
com.ardatis.ventouris.domain.integration.asis.TempInterneOntvangst,
com.ardatis.ventouris.domain.calculationparameters.InkomenGrens,
com.ardatis.ventouris.domain.calculationparameters.BijdrageCategorie,
com.ardatis.ventouris.domain.calculationparameters.BijdrageCategorieGroep,
com.ardatis.ventouris.domain.integration.asis.TempOntvangstKinderbijslag,
com.ardatis.ventouris.domain.calculationparameters.JaarVerhogingParameter,
com.ardatis.ventouris.domain.calculationparameters.KwartaalVerhogingParameter,
com.ardatis.ventouris.domain.UitgaveReeks,
com.ardatis.ventouris.domain.Uitgave,
com.ardatis.ventouris.domain.Terugbetaling,
com.ardatis.ventouris.domain.BedragTerugbetaald,
com.ardatis.ventouris.domain.BijdrageSS</config-property-value>
</config-property>
<config-property>
<description>Plugin used to proxy second class object fields of
managed instances. Must implement kodo.util.ProxyManager.</description>
<config-property-name>ProxyManager</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>default</config-property-value>
</config-property>
<config-property>
<description>Plugin used to cache query results loaded from the
data store. Must implement kodo.datacache.QueryCache.</description>
<config-property-name>QueryCache</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>true</config-property-value>
</config-property>
<config-property>
<description>Plugin used to cache query compilation data. Must
implement java.util.Map. Does not need to be thread-safe -- it will be
wrapped via the Collections.synchronizedMap() method if it does not extend
kodo.util.CacheMap.</description>
<config-property-name>QueryCompilationCache</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>true</config-property-value>
</config-property>
<config-property>
<description>The default lock level to use when loading objects
within non-optimistic transactions. Set to none, read, write, or the
numeric value of the desired lock level for your lock
manager.</description>
<config-property-name>ReadLockLevel</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>read</config-property-value>
</config-property>
<config-property>
<description>Plugin used to communicate commit information among
JVMs. Must implement kodo.event.RemoteCommitProvider.</description>
<config-property-name>RemoteCommitProvider</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value></config-property-value>
</config-property>
<config-property>
<description>Whether or not RemoteCommitEvents will include the
object Ids of objects added during the transaction.</description>
<config-property-name>RemoteCommitTransmitAddObjectIds</config-property-na -
How to fetch all properties with ejb3
I have need to fetch all properties in a Query when loading Entity EJB's in ejb3.0. This is because I'm going to detach the entities from the EntityManager, but want all the properties to be loaded. I have some entities that have simple fields that are normally fetched lazily (BLOBs and CLOBs). I also have relationships to other entities that would also normally be fetched lazily. Finally, I'm trying to do this in generic code that looks like this:
Query q = manager.createQuery("select o from " + variableNameOfOrmClass + " o");
List l = q.getResultList();
So, I can't really name the relationships and do a FETCH JOIN... but rather, I just want to tell the query to "fetch all properties". I also don't want to for EAGER fetching because the majority case is that I'm not going to detach objects from the EntityManager.
Is there a simply way to tell EJBQL (EJB3.0) to fetch all properties at the query time?In this forum, I asked if there is a way to fetch all properties at query time. In the other, I asked if there is a way to force a load of all unfetched properties on an entity, or better yet, a collection of entities, that I've previously queried. Similar, but not the same.
-
I'm pretty sure this is basic stuff, and I should probably know this already, but here goes:
when you execute a query through EntityManager, are results eagerly fetched, or are they being loaded as the result set is iterated through?
I was wondering if when I iterate through only the first 5 results, is the whole result set still being populated?
I've been learning this stuff for a while but, to make matters worse, I was required to learn some LINQ in the mean time, so similar concepts got messed up in my mind... thus this question.
Thanks for the time!It would depend on the implementation of the JDBC driver what it does, but generally you're going to get eager fetching of at least the first level records.
Linked records (non-primitive fields fetched from other tables) may be eagerly or lazily fetched depending on the configuration set. by default however those are eagerly fetched (and that's what JPA means when it talks about eager fetching).
If your dependency tree is deep and the child records are needed relatively rarely (for example you're not going to display them initially after a fetch, but only when explicitly drilling down), lazy fetching of those can improve performance. If they are required to be fetched as the norm, lazy fetching there can cost performance, so it's a design decision that requires some thought. -
Lazy fetching problem with TopLink essentials
[TopLink Warning]: 2008.08.02 08:56:14.656--ServerSession(29131495)--Ignoring LAZY fetch type on element [public byte[] org.mayhem.mail.entity.Message.getRawBytes()] within entity class [class org.mayhem.mail.entity.Message]. All basic mappings default to use EAGER fetching.This is what I get when I start TopLink essesntials based JavaEE server. Why is that ?
No, no..... I knooow that lazy fetching is not required to be supported by a JPA implementor.
The question is why ?
I mean, isnt Toplink the official implementation, and arent all features "supposed" to be implemented?
How can I address this issue ?
I dont want to fetch the bytes on each accessed message ...... ;(TopLink Essentials does not support this optional feature.
EclipseLink 1.0 does, (JPA 2.0 reference impl). EclipseLink is basically the full open sourcing of the TopLink product, where as TopLink Essentials only included "Essential" features.
-- James : [http://www.eclipselink.org] -
My experience migrating Kodo 3.4 to 4.1
Hello Stefan,
I struggled with Kodo 4.0 and gave it up. Kodo 4.1 seems to be a much better
release. I migrated my app in a day. First I managed to run it against 3.4
metadata with some property file changes (migration docs are not very good
and miss few things but may be if you use Kodo automated migration tools it
will do for you what I was doing manually) . If you use lots of custom
filed mappings (especially non-trivial mappings) allocate much more time for
conversion - the whole thing has changed. I have not had chance to convert
my mapping and had to bandate it with externalizers and other things for
now. One thing you lose in kodo3.4 mode is ability to query by interface
since now it must be explicetly.
Couple of tips here
- kodo.Log: kodo(DefaultLevel=INFO, SQL=TRACE...) kodo is no longer valid
logger name
- kodo.jdbc.DBDictionary: oracle(BatchLimit=30) BatchLimit=30 is no longer a
valid option use
kodo.jdbc.SQLFactory: (BatchLimit=50) instead
- kodo.PersistentClasses= ... is no longer works use
kodo.MetaDataFactory: kodo3(Types=....) in kodo3 mode or
kodo.MetaDataFactory: (Types=...) in jdo2 mode
- Any SQL with DATE column is no longer batched leading to 2-3 times
performance drop. The decision swa made based on bugs in oracle 9 drivers in
batching mode. If you have latest drivers (and database) from my experience
you will not have any problems. So to reenable it you can register your own
instance of AdvancedSQL (now a factored out part of DatabaseDictionary):
kodo.jdbc.SQLFactory: (BatchLimit=50,
AdvancedSQL=com.peacetech.jdo.kodo.kodo4.patch.OracleAdvancedSQL)
where OracleAdvancedSQL could look like:
public class OracleAdvancedSQL extends kodo.jdbc.sql.OracleAdvancedSQL {
@Override public boolean canBatch(Column col) {
switch (col.getType()) {
case Types.DATE:
return true;
default:
return super.canBatch(col);
- I have not tested read performance much since I was concentrating on
writes. But write performance even with batch enabled does not seems to be
not up to 3.4 level I observed a consistent 30-40% decrease in performance
while persisting large graph complex of fairly small objects. I ran 3.4 and
4.1 versions side by side against a dedicated Oracle 10 server and noticed
performance decrease of 30-40%
SQL generated by both versions was very close if not identical (I only did
spotcheck) but incase of INSERT you would not expect it any different anyway
I tried profiling 4.1 version and found some significant hot spots but could
not dechipher them in any reasonable time because of huge depth of stacks
and lack of source code. I might try it again if I have time because
performance is critical for us.
- I have not tried any new/advanced features yet. including new mappings,
detachment, data cache, quality of eager fetch so I can not give you any
good feedback on that. At least I can say that this release worth trying -
after migration my application worked as expected except for lower
performance
I also have to say I do not know how well automated migration of kodo 3.4
metadata to jdo2 metadata works (if it exists) because I use my model driven
code generator and I just developed JDO2 plugin for it and regenerated my
metadata from the model (I did not have to gegenerate my java classes of
course)
Alex
Then I created native JDO2 mappings and everythingDenis,
Could you email it to me please shurik at peacetech dot com
Thanks
Alex
"Denis Sukhoroslov" <[email protected]> wrote in message
news:[email protected]...
Alex,
The issue was in version 3.4.1. BEA has provided a patch, no new version.
Denis.
"Alex Roytman" <[email protected]> wrote in message
news:[email protected]...
Denis,
In which version did you observe it and which version fixed it?
Thank you
Alex
"Denis Sukhoroslov" <[email protected]> wrote in message
news:[email protected]...
I don't know, I didn't tried 4.1 yet. It is possible that this issue
was'n exist in kodo 4.x at all.
"Christiaan" <[email protected]> wrote in message
news:[email protected]...
Nice! Is it also solved for 4.1?
regards,
Christiaan
"Denis Sukhoroslov" <[email protected]> wrote in message
news:[email protected]...
Finally, BEA has solved the issue I mentioned. Reading cached PCs
which have embedded objects become much faster (about 10 times in my
tests).
Thank you very much to all why was involved in this job.
Denis.
"Denis Sukhoroslov" <[email protected]> wrote in message
news:[email protected]...
Hi Alex,
I know about default-fetch-group, of course I marked these embedded
fields properly. You're right, it is not a cache miss but an
unnecessary fetch from DB. It's strange that nobody has found this
before. I managed to create a stanalone test case and send it to BEA
support. They agree that it is a bug, but still can't fix the issue.
The test is quite small, so if anyone interested I can send it here.
Denis.
"Alex Roytman" <[email protected]> wrote in message
news:[email protected]...
Hi Denis,
That's very strange. All custom fields such enums etc. are
essentially mapped onto regular JDO mandated types. I use it all the
time and have not observed this behavior but I might have missed it
of course. I have a suspicion that what you are seeing is not cache
misses but rather fetches outside of default fetch group. Keep in
mind that Kodo does not fetch any custom field as part of default
fetch group unless you explicetly specified it in your package.jdo
So, try to mark all your custom mapped fields with
default-fetch-group="true" and I suspect all your extra database
selects will disspear.
Read speed, inded, is always the critical part. I just have not had
chance to play with 4.1 reads enough to say if it is faster or
slower. There are more ways to optimize reads (various flavors of
eager fetches, cutom optimized mapping of collections including
embedding ...) but very few optimizations for updates
Alex
"Denis Sukhoroslov" <[email protected]> wrote in message
news:[email protected]...
Hi Alex.
My question is out of this topic, but it looks like you may have an
answer. BEA support did nothing for the last few months.
We still use kodo 3.4.1. DB is Sybase 12.5.x. In our app we're very
concerned on performance as well. But, we do have much more reads
then writes. So, we're trying to cache as much as possible. Kodo
distributed cache works quite good. At least, it presents better
performance then Gemfire and Tangosol, on the same use cases. But
we found a bug in its caching mechanism: when you have a persistent
class and this class has an embedded attribute of some
non-primitive type (like enum or just a simple complex type with
one or two attributes in it) kodo bypasses cache and performs a
select to DB each time. Have you seen this? Is it possible to solve
via custom mapping, what do you think?
Thanks. Denis.
"Alex Roytman" <[email protected]> wrote in message
news:[email protected]...
Hello Stefan,
I struggled with Kodo 4.0 and gave it up. Kodo 4.1 seems to be a
much better release. I migrated my app in a day. First I managed
to run it against 3.4 metadata with some property file changes
(migration docs are not very good and miss few things but may be
if you use Kodo automated migration tools it will do for you what
I was doing manually) . If you use lots of custom filed mappings
(especially non-trivial mappings) allocate much more time for
conversion - the whole thing has changed. I have not had chance to
convert my mapping and had to bandate it with externalizers and
other things for now. One thing you lose in kodo3.4 mode is
ability to query by interface since now it must be explicetly.
Couple of tips here
- kodo.Log: kodo(DefaultLevel=INFO, SQL=TRACE...) kodo is no
longer valid logger name
- kodo.jdbc.DBDictionary: oracle(BatchLimit=30) BatchLimit=30 is
no longer a valid option use
kodo.jdbc.SQLFactory: (BatchLimit=50) instead
- kodo.PersistentClasses= ... is no longer works use
kodo.MetaDataFactory: kodo3(Types=....) in kodo3 mode or
kodo.MetaDataFactory: (Types=...) in jdo2 mode
- Any SQL with DATE column is no longer batched leading to 2-3
times performance drop. The decision swa made based on bugs in
oracle 9 drivers in batching mode. If you have latest drivers (and
database) from my experience you will not have any problems. So to
reenable it you can register your own instance of AdvancedSQL (now
a factored out part of DatabaseDictionary):
kodo.jdbc.SQLFactory: (BatchLimit=50,
AdvancedSQL=com.peacetech.jdo.kodo.kodo4.patch.OracleAdvancedSQL)
where OracleAdvancedSQL could look like:
public class OracleAdvancedSQL extends
kodo.jdbc.sql.OracleAdvancedSQL {
@Override public boolean canBatch(Column col) {
switch (col.getType()) {
case Types.DATE:
return true;
default:
return super.canBatch(col);
- I have not tested read performance much since I was
concentrating on writes. But write performance even with batch
enabled does not seems to be not up to 3.4 level I observed a
consistent 30-40% decrease in performance while persisting large
graph complex of fairly small objects. I ran 3.4 and 4.1 versions
side by side against a dedicated Oracle 10 server and noticed
performance decrease of 30-40%
SQL generated by both versions was very close if not identical (I
only did spotcheck) but incase of INSERT you would not expect it
any different anyway :-)
I tried profiling 4.1 version and found some significant hot spots
but could not dechipher them in any reasonable time because of
huge depth of stacks and lack of source code. I might try it
again if I have time because performance is critical for us.
- I have not tried any new/advanced features yet. including new
mappings, detachment, data cache, quality of eager fetch so I can
not give you any good feedback on that. At least I can say that
this release worth trying - after migration my application worked
as expected except for lower performance
I also have to say I do not know how well automated migration of
kodo 3.4 metadata to jdo2 metadata works (if it exists) because I
use my model driven code generator and I just developed JDO2
plugin for it and regenerated my metadata from the model (I did
not have to gegenerate my java classes of course)
Alex
Then I created native JDO2 mappings and everything -
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
Maybe you are looking for
-
Difference Between Applet and Swing
Difference Between Applet and Swing
-
RE: Mail notification on changing the status of the spport desk messages
Hi, I am facing problem with the automatic mail notification in service desk configuration. When i create a support desk message in the satellite system, the message appears in crn_dno_monitor in solution manager. When i change the status of the mess
-
Ghostery settings not saved, but must be reset each time I open Firefox.
For several weeks now I am obliged to reset all of the Ghostery settings every time I open Firefox 33.1.1. The Ghostery webpage pops up along with my homepage and all of my prior settings have been removed. The folks at Ghostery tell me the problem i
-
Re: Problem with NOKIA 5220 XpressMusic
I bought a NOKIA 5220 XpressMusic a few days back . Evrything seemed fine , but suddenly I could not access my memory card. It says "Memory card has to be formatted" and then peration failed". Memory card doesnt show up on the computer also. What cou
-
Hi Can we search using arabic text in the search fild in a help created using robohelp? Please advice if any data required please contact me on [email protected] Thanx Abdallah