Hi Bruno,
Bruno CROS wrote:
Hi Armin, and all
Just to clarify my dilemma, i just want to resume my intentions about
configuring my repository.
Consider that model is done, that 90% of transactions are coded (with
reportQuery, and query object and a few getCollections utilizations when
update), and of course, model is complex as you can imagine (lot of
collections ).
Well, according to my last experimentations on 1.0.4, i 'm confined myself
to not use TwoLevelObjectCacheImplementation (i noted a very heavy load when
retrieving object) and not use reference proxy (CGLib) (processes stops
after a while). sorry for that, really.
as I wrote in my previous mail, it would be important to clarify if this
is a problem relating to your object model (object handling) and less
memory of the JVM or a bug in OJB.
I did some simple tests and can't detect any problems with object
materialization and the 2L-Cache. On materialization of objects with
collection references and proxy=true, OJB only materialize the main
object and set the proxy placeholder.
So, it appears to me that the only way to reduce loading time, is to break
some strategical relations, setting up false to many auto-retrieves.
Logically, i chose to "break" collection relation of central classes (
imagine a Customer class referred by 10 others classes.) . This seems to
fast up all my retrieves (globally) but i known now i 'm exposed to have
unwanted behaviour. And that's i can't well imagine.
So, if for my class Customer, all collection descriptors auto-retrieves are
set to false, after my object Customer1 is loaded, collections are not
available to read without doing retrieveAllReference(...) (or its friends
retrieveReference(....). well.Ok.
Now, if idecided to change this object with ODMG ( still without
retrieveAllReference), am i exposed to have all existing records populating
my collections to be deleted? By way of example, imagine Order class,
populating my collections orders in Customer. Did all of my orders disappear
?
if you update the Customer object or you simply add a new Order objects
OJB shouldn't cause problem (I did some tests and can't detect
problems). In the first case OJB will simply update Customer. In the
second case OJB will insert a new Order objects.
I tested this behavior only for 1:n references. m:n references should
behave similar (please test it to verify). 1:1 references will cause
problems.
A second case : still if Customer class have a collection of Orders. If i
get Order1 of Customer1 to update it, (still without any
retrieveAllReference on Customer1),
do i have to expext that something
disappear ?
if you only update Order1 - no.
Anyway I recommend you to add these specific cases to your unit-test
suite to verify OJB behavior.
even if Customer is never locked, just loaded and
(re)referenced.
Don't understand, what do you mean with "just loaded and (re)referenced"?
regards,
Armin
Thanks very very much for the answers.
I hope i will not request you anymore help.
Regards.
On 2/6/06, Armin Waibel <[EMAIL PROTECTED]> wrote:
Hi Bruno,
Bruno CROS wrote:
About my precedent batch troubles:
In fact, a saw my model loaded from every where with all the actual
auto-retrieve="true", this means, every where !! This means too, that
"back" relations are read too, circling too much. This was the cause of
my
OutOfMemoryError.
My model is a big one with a lot of relations, as complex as you can
imagine.
So, i'm asking me about get rid of those auto-retrieve, to get all
objects
reads faster (and avoid a clogging). But i read that for ODMG dev,
precognized settings are auto-retrieve="true" auto-update="none"
auto-delete="none". Do i have to absolutely follow this ? If yes, why ?
In generally the auto-retrieve="true" is mandatory when using the
odmg-api. When using it OJB take a snapshot (copy all fields and
references to other objects) of each object when it's locked. On commit
OJB compare the snapshot with the state of the object on commit. This
way OJB can detect changed fields, new or deleted objects in references
(1:1, 1:n,m:n).
If auto-retrieve is disabled and the object is locked OJB assume that no
references exist or the existing ones are deleted although references
exist and not be deleted. So this can cause unexpected behavior,
particularly with 1:1 references.
The easiest way to solve your problem is to use proxy-references. For
1:n and m:n you can use a collection-proxy:
http://db.apache.org/ojb/docu/guides/basic-technique.html#Using+a+Single+Proxy+for+a+Whole+Collection
For 1:1 references you can use proxies too.
http://db.apache.org/ojb/docu/guides/basic-technique.html#Using+a+Proxy+for+a+Reference
Normally this requires the usage of a interface as persistent object
reference field. But when using CGLib based proxies it's not required
and you can simply set proxy="true" without any changes in your source
code.
http://db.apache.org/ojb/docu/guides/basic-technique.html#Customizing+the+proxy+mechanism
If you can't use proxies (e.g. in a 3-tier application) you can disable
auto-retrieve if you take care and:
- disable implicit locking in generally
- carefully lock all objects before change it (new objects too)
- before you lock an object (for update, delete,...) retrieve the
references of that object using method
PersistenceBroker.retrieveAllReferences(obj)/retrieveReference(...).
At start, I saw that setting auto-retrieve to "true" everywhere wasn't
solution, but all transaction and batch processes were working fine (
until
1.0.4. ), with autoretrieve on all n relations (yes!). Chance !!
But with a
little doubt, I tell to all the dev team to avoid as possible the read
by
iterating collections without any reasons, prefering ReportQuery (single
shot) and direct object queries.
Is that the good way to have a fast and robust application ?
...yep. The fastest way to lookup a single object by PK is to use
PB.getObjectByIdentity(...). If a cache is used this method doesn't
require a DB round trip in most cases.
http://db.apache.org/ojb/docu/tutorials/pb-tutorial.html#Find+object+by+primary+key
Another thing, does defaultPersistenceBroker always return the tx broker
when tx has begun (in 1.0.4)? That's very important.
I hope that i have not to implement with TransactionExt.getBroker method.
All ours reads are with defaultPersistenceBroker.
If you call PBF.defaultPB(...) OJB always return a separate PB instance
(of the 'default' connection defined in jdbc-connection-descriptor) from
the PB-pool using it's own connection.
TransactionExt.getBroker always returns the current used PB instance (of
tx). This behavior never changed.
If you only do read operations with the separate PB instance you will
not run into problems, except if you call tx.flush(). In that case the
objects written to database will not be noticed by the separate PB
instance (until tx.commit - with default DB isolation level).
regards,
Armin
Thank you all in advance.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]