This is a follow-up question to Is it possible to use object composition in PL/SQL?
That question addressed how to create object types in PL/SQL which are mutually dependent (i.e. one attribute of each object is a reference to the other object).
The next problem that I’ve encountered has to do with the object constructors. Here’s the code (logically, student exists inside of person). Also, just to preclude this in the comments, using inheritance is not an option for me.
Person Object
CREATE OR REPLACE TYPE PERSON FORCE AUTHID DEFINER UNDER MYSCHEMA.BASE_OBJECT (
student MYSCHEMA.student,
additional attributes...
CONSTRUCTOR FUNCTION PERSON
RETURN SELF AS RESULT
) NOT FINAL;
CREATE OR REPLACE TYPE BODY PERSON
AS
CONSTRUCTOR FUNCTION PERSON
RETURN SELF AS RESULT IS
BEGIN
self.student := NEW MYSCHEMA.STUDENT(self);
RETURN;
END;
END;
Student Object
CREATE OR REPLACE TYPE STUDENT FORCE AUTHID DEFINER UNDER MYSCHEMA.BASE_OBJECT (
person REF MYSCHEMA.PERSON,
CONSTRUCTOR FUNCTION STUDENT(p_person REF MYSCHEMA.PERSON)
RETURN SELF AS RESULT
) NOT FINAL;
CREATE OR REPLACE TYPE BODY STUDENT
AS
CONSTRUCTOR FUNCTION STUDENT(p_person REF MYSCHEMA.PERSON)
RETURN SELF AS RESULT IS
BEGIN
self.person := p_person;
RETURN;
END;
END;
This code will compile without any errors except for the following line within the PERSON constructor which instantiates a STUDENT object inside of PERSON:
self.student := NEW MYSCHEMA.STUDENT(self);
Which throws the following error:
Error(22,29): PLS-00306: wrong number or types of arguments in call to 'STUDENT'
And so, dear friends, I seek your help again. I’m guessing that there is an additional parameter that is being passed implicitly into the STUDENT constructor, but that’s just a guess.
Thanks.
A
REFmust refer to a row. You cannot passSELF, since it is not a reference.One way to make this work is to create a hidden table:
And every instance secrently creates a row in that table:
This seems to work, but probably has really horrible side-affects that nobody would want in a real production environment.
Here’s the full script: