|
Home > Archive > Apache JDO Project > September 2005 > Inheritance test schema 2 : "subclass-table" and "identity" strate
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Inheritance test schema 2 : "subclass-table" and "identity" strate
|
|
| Andy Jefferson 2005-09-27, 5:45 pm |
| The Schema 2 inheritance test provokes a question regarding
autoassign/identity strategy when using "subclass-table" strategy. We have 3
classes Employee, PartTimeEmployee, FullTimeEmployee. The Employee class uses
"subclass-table" and the 2 subclasses use "new-table" inheritance strategy.
This maps to 2 tables in the datastore
CREATE TABLE fulltimeemployees
(
DATASTORE_IDENTITY INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY,
...
)
CREATE TABLE parttimeemployees
(
DATASTORE_IDENTITY INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY,
...
)
OK, so what's the problem ?
Well, the problem is that "identity" strategy has been specifed in the ORM
file for both of these subclasses (and the DATASTORE_IDENTITY column is
IDENTITY too). This means that when we persist a FullTimeEmployee, an object
is inserted into "fulltimeemployees" and could be given id 1 (by the
datastore, since it is effectively managing "identity" strategy), and when we
insert a PartTimeEmployee, an object is inserted into "parttimeemployees" and
this could also be given id 1 (since the datastore manages that tables ids
too) !!! The "IDENTITY" keyword is managing ids for that RDBMS table only.
This would break many things. If I call getObjectById() passing in Employee,
and id value of 1 it wouldn't know which subclass it should use if we have DB
entries for a FullTimeEmployee (1) and a PartTimeEmployee (1).
Is the JDO impl supposed to guarantee uniqueness of ids in this situation ?
How ? For the case of the TCK it could be changed to "increment" strategy
maybe and then the JDO impl could manage these values itself perhaps. In the
real world the JDO impl could throw an exception in this situation (where
there is no "base" table that is effectively used to provide uniqueness of
ids in the inheritance tree)
Comments ?
--
Andy
| |
| Michael Watzek 2005-09-28, 5:45 pm |
| Hi Andy,
> The Schema 2 inheritance test provokes a question regarding
> autoassign/identity strategy when using "subclass-table" strategy. We have 3
> classes Employee, PartTimeEmployee, FullTimeEmployee. The Employee class uses
> "subclass-table" and the 2 subclasses use "new-table" inheritance strategy.
> This maps to 2 tables in the datastore
>
> CREATE TABLE fulltimeemployees
> (
> DATASTORE_IDENTITY INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY,
> ...
> )
>
> CREATE TABLE parttimeemployees
> (
> DATASTORE_IDENTITY INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY,
> ...
> )
>
> OK, so what's the problem ?
>
> Well, the problem is that "identity" strategy has been specifed in the ORM
> file for both of these subclasses (and the DATASTORE_IDENTITY column is
> IDENTITY too). This means that when we persist a FullTimeEmployee, an object
> is inserted into "fulltimeemployees" and could be given id 1 (by the
> datastore, since it is effectively managing "identity" strategy), and when we
> insert a PartTimeEmployee, an object is inserted into "parttimeemployees" and
> this could also be given id 1 (since the datastore manages that tables ids
> too) !!! The "IDENTITY" keyword is managing ids for that RDBMS table only.
> This would break many things. If I call getObjectById() passing in Employee,
> and id value of 1 it wouldn't know which subclass it should use if we have DB
> entries for a FullTimeEmployee (1) and a PartTimeEmployee (1).
I'm not sure what you mean by "getObjectById() passing in Employee".
The object model specifies that class Employee is abstract. Thus, there
cannot exist persistent instances of Employee which are not instances of
Employee subclasses. This means that there are no object id instances
of class Employee.
Maybe you mean that two datastore objectid instances, one for
FullTimeEmployee and the other for PartTimeEmployee, having the same
value in the database wrt their identity columns (e.g. 1) would equal in
the object model?
Regards,
Michael
>
> Is the JDO impl supposed to guarantee uniqueness of ids in this situation ?
> How ? For the case of the TCK it could be changed to "increment" strategy
> maybe and then the JDO impl could manage these values itself perhaps. In the
> real world the JDO impl could throw an exception in this situation (where
> there is no "base" table that is effectively used to provide uniqueness of
> ids in the inheritance tree)
>
> Comments ?
>
--
-------------------------------------------------------------------
Michael Watzek Tech@Spree Engineering GmbH
mailto:mwa.tech@spree.de Buelowstr. 66
Tel.: ++49/30/235 520 36 10783 Berlin - Germany
Fax.: ++49/30/217 520 12 http://www.spree.de/
-------------------------------------------------------------------
| |
| Andy Jefferson 2005-09-28, 5:45 pm |
| Hi Michael,
>
> I'm not sure what you mean by "getObjectById() passing in Employee".
> The object model specifies that class Employee is abstract. Thus, there
> cannot exist persistent instances of Employee which are not instances of
> Employee subclasses. This means that there are no object id instances
> of class Employee.
I mean that any user can call pm.getObjectById(id), and they could construct
an "id" where the id is created as being for Employee with value "1". They
would do this if they knew they had an instance of Employee (or subclass)
that has an id of 1. The JDO impl then has to go off, realise that there are
no implementations of Employee as such, and find the right subclass for this
object.
There should be *no way* of having a FullTimeEmployee with id "1" _and_ a
PartTimeEmployee with id "1". They are 2 different objects and the id should
be unique in an inheritance tree. With the situation in this test case
currently they aren't, because there are 2 root tables (in this inheritance
tree) and both are defined as having "IDENTITY" columns, so whenever anything
is inserted into either a new id is allocated in that particular table
(independent of the identity values allocated in the other table).
It would work fine if Employee had its own table since then there is 1 root
table EMPLOYEE which would be the only table using IDENTITY. Sadly once you
include subclass-table at the root level you get this problem. "autoassign"
and "identity" both imply using the underlying datastore mechanisms and both
will fall foul of this problem.
--
Andy
| |
| Michael Watzek 2005-09-28, 5:46 pm |
| Hi Andy,
> Hi Michael,
>
>
>
>
> I mean that any user can call pm.getObjectById(id), and they could construct
> an "id" where the id is created as being for Employee with value "1". They
> would do this if they knew they had an instance of Employee (or subclass)
> that has an id of 1.
My understanding is that your scenario applies to datastore identity.
Applications can only construct objectid instances in case of
application identity. So, how would an application get an Employee
objectid instance?
Do you agree that in case of datastore identity getObjectById can be
resolved for FullTimeEmployee/PartTimeEmployee objectid instances, even
if there are rows in tables fulltimeemployees and parttimeemployees
having the same pk values?
The JDO impl then has to go off, realise that there are
> no implementations of Employee as such, and find the right subclass for this
> object.
> There should be *no way* of having a FullTimeEmployee with id "1" _and_ a
> PartTimeEmployee with id "1". They are 2 different objects and the id should
> be unique in an inheritance tree.
My understanding is that this applies to application identity only.
There, you have the same objectid class for all classes in an
inheritance hierarchy.
Regards,
Michael
With the situation in this test case
> currently they aren't, because there are 2 root tables (in this inheritance
> tree) and both are defined as having "IDENTITY" columns, so whenever anything
> is inserted into either a new id is allocated in that particular table
> (independent of the identity values allocated in the other table).
>
> It would work fine if Employee had its own table since then there is 1 root
> table EMPLOYEE which would be the only table using IDENTITY. Sadly once you
> include subclass-table at the root level you get this problem. "autoassign"
> and "identity" both imply using the underlying datastore mechanisms and both
> will fall foul of this problem.
>
>
--
-------------------------------------------------------------------
Michael Watzek Tech@Spree Engineering GmbH
mailto:mwa.tech@spree.de Buelowstr. 66
Tel.: ++49/30/235 520 36 10783 Berlin - Germany
Fax.: ++49/30/217 520 12 http://www.spree.de/
-------------------------------------------------------------------
| |
| Andy Jefferson 2005-09-28, 5:46 pm |
| Hi Michael,
> My understanding is that your scenario applies to datastore identity.
> Applications can only construct objectid instances in case of
> application identity. So, how would an application get an Employee
> objectid instance?
I was quoting one example of where things break in this situation. I can
certainly create a datastore identity (of the JPOX OID type, since datastore
id is JDO impl specific) with Employee as the class and 1 as the value. The
fact remains that you're creating, by the specification of IDENTITY type, and
"identity" strategy, objects which have the same "key" in their id in the
same inheritance tree, and so issues will result. This was one example.
> Do you agree that in case of datastore identity getObjectById can be
> resolved for FullTimeEmployee/PartTimeEmployee objectid instances, even
> if there are rows in tables fulltimeemployees and parttimeemployees
> having the same pk values?
I agree that *if* I have a full complete id with correct class, then I can
find the row, since the class has been specified. What I'm saying is that
there situations where you only have the "id" and not the class. The
pm.getObjectById() is one example.
Let's have another example :-)
I've got a class (e.g Project) with a collection field and I'm storing objects
of type Employee (declared in the metadata). I have a join table for storing
the linkage between owner and element. I need to find the elements of the
collection when retrieving the owner object. Now the only thing in the join
table of use is a column which has the "id" of the Employee object that is
contained in this collection. It doesn't say, "this is a FullTimeEmployee
with id 1". It just says "its an Employee" (from the collection MetaData) and
the FK column says "1" is the id of the object. So which element table do I
join to ? Do I go to FULLTIMEEMPLOYEE ? Do I go to PARTTIMEEMPLOYEE ? How do
i decide ?
Having duplicate id "values" in an inheritance tree representing different
objects is a "bad thing".
--
Andy
| |
| Michael Watzek 2005-09-28, 5:46 pm |
| Hi Andy,
> Hi Michael,
>
>
>
>
> I was quoting one example of where things break in this situation. I can
> certainly create a datastore identity (of the JPOX OID type, since datastore
> id is JDO impl specific) with Employee as the class and 1 as the value. The
> fact remains that you're creating, by the specification of IDENTITY type, and
> "identity" strategy, objects which have the same "key" in their id in the
> same inheritance tree, and so issues will result. This was one example.
>
>
>
>
> I agree that *if* I have a full complete id with correct class, then I can
> find the row, since the class has been specified. What I'm saying is that
> there situations where you only have the "id" and not the class. The
> pm.getObjectById() is one example.
>
> Let's have another example :-)
> I've got a class (e.g Project) with a collection field and I'm storing objects
> of type Employee (declared in the metadata). I have a join table for storing
> the linkage between owner and element. I need to find the elements of the
> collection when retrieving the owner object. Now the only thing in the join
> table of use is a column which has the "id" of the Employee object that is
> contained in this collection. It doesn't say, "this is a FullTimeEmployee
> with id 1". It just says "its an Employee" (from the collection MetaData) and
> the FK column says "1" is the id of the object. So which element table do I
> join to ? Do I go to FULLTIMEEMPLOYEE ? Do I go to PARTTIMEEMPLOYEE ? How do
> i decide ?
Now I understand what you mean :-). You are completely right: That would
be an odd schema.
Preventing this situation, the inheritance proposal for mapping 2 puts
some constraints on the object model which I summarized in mail
"Inheritance proposal" sent on 8/8/2005. Obviously, we must document
them in the wiki which has not been done yet. This is an excerpt:
"- Mapping 2:
....
Some additional constraints: Managers, mentors, hradvisors, and
employees of the month are fulltime employees. Only fulltime employees
can have insurances, can be project members, and can be project
reviewers. Separate phone number type tables for persons, fulltime
employees, and parttime employees."
These constraints are reflected by the database schema for mapping 2. As
there is no employees table, fks referencing employees in schema0
reference either fulltimeemployees or parttimeemployees in schema2. In
particular, there are 3 phone number tables in schema2, one referencing
persons, one referencing fulltimeemployees, and one referencing
parttimeemployees.
Do these constraints solve your concerns?
Regards,
Michael
>
> Having duplicate id "values" in an inheritance tree representing different
> objects is a "bad thing".
>
>
--
-------------------------------------------------------------------
Michael Watzek Tech@Spree Engineering GmbH
mailto:mwa.tech@spree.de Buelowstr. 66
Tel.: ++49/30/235 520 36 10783 Berlin - Germany
Fax.: ++49/30/217 520 12 http://www.spree.de/
-------------------------------------------------------------------
| |
| Andy Jefferson 2005-09-28, 5:46 pm |
| Hi Michael,
> Preventing this situation, the inheritance proposal for mapping 2 puts
> some constraints on the object model which I summarized in mail
> "Inheritance proposal" sent on 8/8/2005. Obviously, we must document
> them in the wiki which has not been done yet. This is an excerpt:
>
> "- Mapping 2:
> ...
> Some additional constraints: Managers, mentors, hradvisors, and
> employees of the month are fulltime employees. Only fulltime employees
> can have insurances, can be project members, and can be project
> reviewers. Separate phone number type tables for persons, fulltime
> employees, and parttime employees."
>
> These constraints are reflected by the database schema for mapping 2. As
> there is no employees table, fks referencing employees in schema0
> reference either fulltimeemployees or parttimeemployees in schema2. In
> particular, there are 3 phone number tables in schema2, one referencing
> persons, one referencing fulltimeemployees, and one referencing
> parttimeemployees.
>
> Do these constraints solve your concerns?
Well in the datastore adding these restrictions on the FKs may have the effect
of limiting where an object can be stored (from the datastores point of
view), but how does the JDO implementation know this ? It has metadata -
there is nothing in the MetaData that defines that they can only be a
FullTimeEmployee. The MetaData (and the Java class) are the JDO input that
the JDO implementation works from. A "mentor" for example is an Employee
object type in a 1-1 relation mapped with a single FK (yes, I see your
restrictions in the schema SQL). The MetaData however doesn't specify
anything else. Consequently the JDO impl will always try to find the Employee
object that is at the other end of the relation. It will have to join with
both possible subclasses of Employee to find the one with the correct id.
Will this lead to issues with the data populated by the TCK test ?
You're expecting the JDO impl to go down through the users schema and find out
that the FK is to "FULLTIMEEMPLOYEES" and so eliminate any possible join to
"PATTIMEEMPLOYEES" ?
I've not gone through the data created by the test, only the first few records
and the fact that it is creating these duplicate records (as I call them).
Without analysing the data that the test is adding further I can't do any
more than point out these issues and the fact that there are many possible
issues with having FullTimeEmployee and PartTimeEmployee objects with the
same id. The simplest solution IMHO would be to choose an inheritance
strategy that allows the JDO implementation to keep them unique. I'm not
going to have any time to look further 'til early next week.
--
Andy
|
|
|
|
|