Hi Gautam,
Virgo Smart wrote:
Hello,
I figured out what the problem is. I am using a table per subclass mapping strategy
using sub-class/table FK referencing to the super-class/table PK.
However there still is a problem with generating unique values for the id field
across
all extents. Adapting an example from the Apache-OJB site, consider the scenario
Manager and Consultant classes extend Executive extends Employee where in each class
is mapped to their own tables.
EMPLOYEE table has columns ID, NAME.
EXECUTIVE table has columns ID, DEPT, EMP_ID (where EMP_ID is a FK referencing
EMPLOYEE.ID).
MANAGER table has columns ID, CONSORTIUM_ID, EXEC_ID (where EXEC_ID is a FK
referencing EXECUTIVE.ID).
CONSULTANT table has columns ID, EXT_REF_CODE, EXEC_ID (where EXEC_ID is a FK
referencing EXECUTIVE.ID).
The class descriptors for Employee, Executive, Manager and Consultant are
defined as follows.
<class-descriptor class="Employee" table="EMPLOYEE">
<extent-class class-ref="Executive" />
<field-descriptor
name="id"
column="ID"
jdbc-type="BIGINT"
primarykey="true"
autoincrement="true"
/>
<field-descriptor
name="name"
column="NAME"
jdbc-type="VARCHAR"
/>
</class-descriptor>
<class-descriptor class="Executive" table="EXECUTIVE">
<extent-class class-ref="Manager" />
<extent-class class-ref="Consultant" />
<field-descriptor
name="id"
column="ID"
jdbc-type="BIGINT"
primarykey="true"
autoincrement="true"
/>
<field-descriptor
name="department"
column="DEPT_ID"
jdbc-type="BIGINT"
/>
<field-descriptor
name="employeeId"
column="EMP_ID"
jdbc-type="BIGINT"
access="anonymous"
/>
<reference-descriptor name="super"
class-ref="Employee"
>
<foreignkey field-ref="employeeId"/>
</reference-descriptor>
</class-descriptor>
<class-descriptor class="Manager" table="MANAGER">
<field-descriptor
name="id"
column="ID"
jdbc-type="BIGINT"
primarykey="true"
autoincrement="true"
/>
<field-descriptor
name="consortiumId"
column="CONSORTIUM_ID"
jdbc-type="BIGINT"
/>
<field-descriptor
name="executiveId"
column="EXEC_ID"
jdbc-type="BIGINT"
access="anonymous"
/>
<reference-descriptor name="super"
class-ref="Executive"
>
<foreignkey field-ref="executiveId"/>
</reference-descriptor>
</class-descriptor>
<class-descriptor class="Consultant" table="CONSULTANT">
<field-descriptor
name="id"
column="ID"
jdbc-type="BIGINT"
primarykey="true"
autoincrement="true"
/>
<field-descriptor
name="externalRefCode"
column="EXT_REF_CODE"
jdbc-type="VARCHAR"
/>
<field-descriptor
name="executiveId"
column="EXEC_ID"
jdbc-type="BIGINT"
access="anonymous"
/>
<reference-descriptor name="super"
class-ref="Executive"
>
<foreignkey field-ref="executiveId"/>
</reference-descriptor>
</class-descriptor>
I wish to have the ID column values unique across all the 4 database tables.
Currently when I insert 1 Manager and 1 Consultant, data in stored in the table
as follows.
EMPLOYEE : Two rows are inserted. (1 row each for Manager and Consultant). Here
assuming that Manager data was first to be stored, ID = 1 for Manager and ID =
2 for Consultant.
EXECUTIVE: Two rows are inserted with ID same as those stored in the EMPLOYEE
table.
MANAGER : 1 row inserted. ID = 1
CONSULTANT : 1 row inserted. ID = 1
What I wish to have is the ID value in the CONSULTANT table to be set to 2
(matching value stored in EMPLOYEE and EXECUTIVE tables) instead of 1.
I am trying to use SequenceManager implementations but am not able to generate
a sequence number. Further more I am not sure if using sequence manager would
solve this problem. I some how want to indicate to the OJB broker to use the id
attribute value of the base class when persisting the child classes.
This isn't a SequenceManager issue, so a user-based SequenceManager
implementation will not help.
I think there is a documentation bug in OJB and when using
TPS-inheritance with foreign key settings there is a bug when overriding
the id fields in sub-classes.
The autoincrement setting in the sub-classes will always be ignored by
OJB (and the PK of the base table will be copied to all sub-table PK
columns, thus there is no need to use a FK field), except the id field
is overridden in the sub-class (then the mapping via FK is mandatory):
class Employee
{
Integer id;
...
}
class Executive extends Employee
{
// override field
Integer id;
...
}
But this will not work correct with current version of OJB. Will try to
fix this ASAP.
Don't declare "extent-class" entries when using TPS inheritance (think
this could cause side-effects).
So I recommend to use the "normal" TPS inheritance.
regards,
Armin
Regards,
Gautam
On Fri, 17 Nov 2006 Armin Waibel wrote :
Hi,
Virgo Smart wrote:
In my attempt to solve a problem when retrieving object references
(collection and simple) from a domain/persistent class, I looked up
Identity.java class source as I suspect identity object as the source of the
problem.
The equals method of the identity class does not seem to take the object's real
class type (m_objectsRealClass attrib) into account when comparing two
identities. Is the equals method correctly implemented ?
yep! It's expected behavior. In certain circumstances it's not possible to resolve the
real class of an object when building the Identity. For example: Interface Article with
real classes CdArticle and BookArticle (in mapping file Article is declared with
"extent" classes CdArticle and BookArticle). Now we define a 1:1 reference from
Class A to Article. In this case we don't know the real class but the top-level class and
can build the Identity object using the FK fields (in class A) and the top-level class.
Long time ago it seems to be a good solution to use the top-level class with PK fields as
object Identity. This help to avoid problems with "declared class" (interface,
abstract class or real class) and the real class of an object in references.
Could you describe more detailed (e.g. with pseudo code or a unit test + class
mapping) what your problem is?
regards,
Armin
Equals method in Identity.java:
public boolean equals(final Object obj)
{
if(this == obj) return true;
boolean result = false;
if (obj instanceof Identity)
{
final Identity id = (Identity) obj;
result = m_objectsTopLevelClass.equals(id.m_objectsTopLevelClass)
&& isTransient == id.isTransient;
if(result)
{
final Object[] otherPkValues = id.m_pkValues;
result = m_pkValues.length == otherPkValues.length;
if(result)
{
for (int i = 0; result && i < m_pkValues.length; i++)
{
result = (m_pkValues[i] == null) ? (otherPkValues[i] ==
null)
: m_pkValues[i].equals(otherPkValues[i]);
// special treatment for byte[]
if (!result && m_pkValues[i] instanceof byte[] &&
otherPkValues[i] instanceof byte[])
{
result = Arrays.equals((byte[]) m_pkValues[i],
(byte[]) otherPkValues[i]);
}
}
}
}
}
return result;
}
Javadoc for Identity.java class:
public class Identity
extends java.lang.Object
implements java.io.Serializable
Represents the identity of an object. It's composed of:
class of the real object
top-level class of the real object (could be an abstract class or interface or the class of the object itself), used to make an object unique across extent classes
an array of all primary key value objects
a flag which indicates whether this is a transient Identity (identity of a non-persistent, "new" object) or a persistent Identity (identity object of a persistent, "already written to datastore" object).
Thanks and Regards,
Gautam.
---------------------------------------------------------------------
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]