Hi all OJB gurus and lurkers,
I have a disturbing problem that I can´t seem to figure out.
In order to fully explain the problem a small introduction is probably
needed.....bare with me :-)
The tables:
create table object (
object_id number(14) not null,
valid_from date not null,
valid_to date not null,
objecttype_id number(6) not null,
county_id char(2),
primary key(object_id, valid_from, valid_tom)
)
create table objectproperties (
property_id number(14) not null,
valid_from date not null,
valid_to date not null,
propertytype_id number(6) not null,
object_id number(14) not null,
valuetype char(1) not null,
value_text varchar(255),
value_date date,
value_clob clob,
value_blob blob,
primary key(property_id, valid_from, valid_to)
)
create table relation (
relation_id number(14) not null,
valid_from date not null,
valid_to date not null,
relationtype_id number(6) not null,
object_id_source number(14) not null,
object_id_target number(14) not null,
primary key(relation_id, valid_from, valid_to)
)
create table relationproperties (
property_id number(14) not null,
valid_from date not null,
valid_to date not null,
propertytype_id number(6) not null,
relation_id number(14) not null,
valuetype char(1) not null,
value_text varchar(255),
value_date date,
value_clob clob,
value_blob blob,
primary key(property_id, valid_from, valid_to)
)
Below is an attempt to illustrate the database schema. arrows are
depicting foreign keys.
OBJECT < OBJECTPROPERTIES
^ ^
REALTION < RELATIONPROPERTIES
Ok, so what does this give us?
We´ve got a model where objects, which can have properties, can be stored.
Objects can have relations to other objects in a m:n manner, even
circular, given the schema.
Now, the trick here is that the primary keys are composite, they consist
of the id AND the timestamp.
The timestamps are there to journal the operations. When an update takes
place,
it is really supposed to be an update and an insert. The existing tuple
with a given id should be updated on valid_to and the
new tuple with the same id should have the same date as valid_from. New
tuple´s valid_to is 9999-12-31 00:00:00.
In order to do this with OJB, we introduced views on theese tables,
exposing only valid (timewise) tuples.
On theese views are triggers that handles the validity-fields when
updating/inserting/deleting on the view.
So in our repository only the views are mentioned.
Also, we use SequenceManagerNextVal to hold all of the primary keys
involved.
The Beans:
Public class MyObject {
long object_id;
Calendar validFrom;
Calendar validTo;
Vector sourceRelations;
Vector targetRelations;
Vector properties;
// type-bean and id´s ignored
// gettters and setters ignored
}
Public class MyRelation {
Calendar validFrom;
Calendar validTo;
MyObject sourceObject;
MyObject targetObject;
long sourceObjectId;
long targetObjectId;
// type-bean and id ignored;
// getters and setters ignored
}
The Mapping:
<class-descriptor class="MyObject" table="object_v">
<collection-descriptor name="sourceRelations"
element-class-ref="MyRelation" auto-update="false" auto-delete="false"
refresh="true">
<inverse-foreignkey field-id-ref="5"/>
</collection-descriptor>
<collection-descriptor name="targetRelations"
element-class-ref="MyRelation" auto-update="false" auto-delete="false"
refresh="true">
<inverse-foreignkey field-id-ref="6"/>
</collection-descriptor>
</class-descriptor>
<class-descriptor class="MyRelation" table="relation_v"
<reference-descriptor name="source"
class-ref="se.raa.kms.server.persistence.data.RaaObject"
auto-update="false" auto-delete="false" auto-retrieve="true">
<foreignkey field-id-ref="5"/>
</reference-descriptor>
<reference-descriptor name="target"
class-ref="se.raa.kms.server.persistence.data.RaaObject"
auto-update="false" auto-delete="false" auto-retrieve="true">
<foreignkey field-id-ref="6"/>
</reference-descriptor>
</class-descriptor>
We have written a wrapper, a "PersistanceManger" that bascially is our
buissness-logic layer above PersistenceBroker.
The PersistenceManager is also an interface used by axis to expose the
service as a webservice.
Since our beans are sent over soap they have to be as clean and bare
bones as possibly, not using types that can be serialized as xml and so on.
This wrapper iterates and stores the object´s and their children
recursively, calling broker.store(...).
Before every operation the validity-fields in our beans are set to null,
to allow the triggers to operate correctly.
In order to handle
The problem:
Tuple´s are modified by the database during the operation, and the the
beans doesn´t get updated reflecting with the new timestamps
created by the database.
We have tried to use broker.removeFrom cache(...) followed by an
broker.getObjectByIdentity(...) on every object affected
by changes. This gives us correct values on the timestamps, but creates
duplicate Relation objects on both object´s source/target collections.
Seems like everything gets refresh twice.
We have tried almost all combinations of auto-delete, auto-update and
refresh in order to get the timestamp fields updated from the beans.
I have given instance-callback through PersistenceBrokerAware interface
a thought, could this be the way to do it?
Regards,
Per-Olof
|