persistence@glassfish.java.net

Re: ManyToOne: Missing meta data for class [java.lang.String]

From: Sanjeeb Kumar Sahoo <Sanjeeb.Sahoo_at_Sun.COM>
Date: Thu, 14 Sep 2006 00:25:57 +0530

Thanks for clarifying that you have made a conscious decision to
annotate RegistryObject as a MappedSuperclass. A MappedSuperclass can't
be target of a relationship, but your object model have such
relationships. It should have been an Abstract Entity class, but then
your relational schema can't be changed and TopLink Essential does not
support TABLE_PER_CLASS strategy. So, I can't think of a solution right
now. Without such constraints, I would have coded like this (it answers
your question about PropertyPK class):

@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS or some other suitable strategy)
public abstract class RegistryObject implements Serializable {

    @Id
    @Column(name = "ID", nullable = false)
    protected String id;

    @OneToMany (mappedBy="parent", cascade={...})
    protected Collection<Property> properties;

    @OneToMany (mappedBy="classifiedObject",
cascade={CascadeType.REMOVE, CascadeType.PERSIST})
    protected Collection<Classification> classifications;

    ....accessor methods....
}

@Entity
@Table(name = "SERVICE")
public class Organization extends RegistryObject {
...
}

@Entity
@Table(name = "CLASSIFICATION")
public class Classification extends RegistryObject {
    @ManyToOne
    @JoinColumn(name = "CLASSIFIEDOBJECT", referencedColumnName = "id", nullable = false)
    private RegistryObject classifiedObject;
...
}

@Entity
@Table(name = "PROPERTY")
public class Property implements Serializable {

    @EmbeddedId
    protected PropertyPK PropertyPK;

    @Column(name = "VALUE")
    private String value;

    // this is a read-only column as the JoinColumn name is same as the column name for parent field in Embeddable class
    @ManyToOne
    @JoinColumn(name = "PARENT", referencedColumnName = "id", insertable = false, updatable = false, nullable = false)
    private RegistryObject parent;
}

@Embeddable
public class PropertyPK implements Serializable {

    @Column(name = "SEQUENCEID", nullable = false)
    private int sequenceid;

    @Column(name = "NAME_", nullable = false)
    private String name;

    @Column(name = "PARENT", nullable = false)
    private String parent;

...
}


I don't know when we will support TABLE_PER_CLASS strategy.
Thanks,
Sahoo

Farrukh S. Najmi wrote:
> Thanks for the quick response Sahoo. Please see inline below...
>
> Sanjeeb Kumar Sahoo wrote:
> ....
>
>> 3. Why are you using MappedSuperclass? Check section #2.1.9 of the JPA
>> spec to see if you wanted to use Abstract Entity class instead of
>> MappedSuperclass.
>>
>
> I have a restriction that I cannot change the relational schema.
> The leaf classes map to the TABLE_PER_CLASS InheritanceType AFAICT.
>
> If I were to make the RegistryObjec and abstract Entity class them the
> relational schema requires
> @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
>
> The InheritanceType.TABLE_PER_CLASS is not supported by Toplink.
>
> Am I correct?
>
> How then do I deal with my problem?
>
> BTW any guess as to when InheritanceType.TABLE_PER_CLASS will be supported?
>
>
>> 4. You are using @ManyToOne in your embeddable class PropertyPK. That's
>> not allowed. See section #9.1.35 of the JPA spec.
>>
>
> Sorry but I did not get this one. I need to specify the reverse
> relationship in the Property class to the RegistryObject class using the
> parent field in the Property class as foreign key to the leaf classes
> derived from RegistryObject class somehow. The parent field is defined
> in PropertyPK. How do I deal with this issue?
>
> Thanks again for your help.
>
>
>> Sahoo
>>
>> Farrukh S. Najmi wrote:
>>
>>> My apologies in advance for a long email. I have tried to simplify the
>>> problem decsription as best as possible and have searched archives and
>>> read the spec. Thanks in advance for your help.
>>>
>>> I am migrating my application from using JDBC to using Java Persistence
>>> API. The schema is fixed by an ISO standard (cannot be changed) and
>>> represents the relational mapping of an OO model with inheritance
>>> semantics.
>>>
>>> A simplified version of the inheritance Model is shown here:
>>>
>>> http://ebxmlrr.sourceforge.net/tmp/Simplifiedclassdiagram.png
>>>
>>> The UML diagram is mapped to the schema such that:
>>>
>>> -Each leaf class (Oragnization, and Classification) has its own table
>>>
>>> -There is no table defined for the base class RegistryObject
>>>
>>> -All base class attributes are duplicated in the leaf class table
>>>
>>> -A View is defined for the base class RegistryObject which allows for
>>> querying at the base class level.
>>>
>>> -The base class has a collection of composed (Embedded) object Property
>>> which uses a composite id and has a foreign key to join with the parent
>>> Leaf class (Organization or Classification).
>>>
>>> -The base class has a collection of composed object (but not embedded
>>> from a relational standpoint) Classification which uses a foreign key to
>>> join with the parent Leaf class (Organization or Classification).
>>>
>>> A simplified version schema is as follows:
>>>
>>> CREATE TABLE Organization (
>>> id VARCHAR(256) NOT NULL PRIMARY KEY,
>>> ...
>>> );
>>>
>>> CREATE TABLE Classification (
>>> id VARCHAR(256) NOT NULL PRIMARY KEY,
>>> --Foreign key to parent RegistryObject being classified by this object
>>> classifiedObject VARCHAR(256) NOT NULL,
>>> ...
>>> );
>>>
>>> CREATE TABLE Property (
>>> --Multiple rows of Property make up a single Property to support
>>> --collection of values in a single logical Property
>>> --The sequenceid is to keep the collection of values ordered
>>> sequenceId INT NOT NULL,
>>> name_ VARCHAR(256) NOT NULL,
>>> value VARCHAR(256),
>>> --The parent RegistryObject that this is a Property for
>>> parent VARCHAR(256) NOT NULL,
>>> PRIMARY KEY (parent, name_, sequenceId)
>>> );
>>>
>>> CREATE VIEW Identifiable (
>>> --Base class Attributes
>>> id,
>>> ...
>>> ) AS
>>> SELECT
>>> id,
>>> ...
>>> FROM Organization
>>> UNION ALL
>>> SELECT
>>> id,
>>> ...
>>> FROM Person
>>>
>>> The Entity classes I have defined for above schema are as follows:
>>>
>>> @MappedSuperclass
>>> public abstract class RegistryObject implements Serializable {
>>>
>>> @Id
>>> @Column(name = "ID", nullable = false)
>>> protected String id;
>>>
>>> @OneToMany (mappedBy="parent", cascade={CascadeType.REMOVE,
>>> CascadeType.PERSIST})
>>> private Collection<Property> properties;
>>>
>>> @OneToMany (mappedBy="classifiedObject",
>>> cascade={CascadeType.REMOVE, CascadeType.PERSIST})
>>> protected Collection<Classification> classifications;
>>>
>>> ....accessor methods....
>>> }
>>>
>>> @MappedSuperclass
>>> public abstract class RegistryObject implements Serializable {
>>>
>>> @Id
>>> @Column(name = "ID", nullable = false)
>>> protected String id;
>>>
>>> @OneToMany (mappedBy="parent", cascade={CascadeType.REMOVE,
>>> CascadeType.PERSIST})
>>> private Collection<Property> properties;
>>>
>>> ....accessor methods....
>>> }
>>>
>>> @Entity
>>> @Table(name = "SERVICE")
>>> public class Organization extends RegistryObject {
>>> ...
>>> }
>>>
>>> @Entity
>>> @Table(name = "CLASSIFICATION")
>>> public class Classification extends RegistryObject {
>>> @ManyToOne
>>> @JoinColumn(name = "CLASSIFIEDOBJECT", referencedColumnName = "id",
>>> table = "RegistryObject", nullable = false)
>>> private String classifiedObject;
>>>
>>>
>>> ...
>>> }
>>>
>>> @Entity
>>> @Table(name = "PROPERTY")
>>> public class Property implements Serializable {
>>>
>>> @EmbeddedId
>>> protected PropertyPK PropertyPK;
>>>
>>> @Column(name = "VALUE")
>>> private String value;
>>> ...
>>> }
>>>
>>> @Embeddable
>>> public class PropertyPK implements Serializable {
>>>
>>> @Id
>>> @Column(name = "SEQUENCEID", nullable = false)
>>> private int sequenceid;
>>>
>>> @Id
>>> @Column(name = "NAME_", nullable = false)
>>> private String name;
>>>
>>> @Id
>>> @ManyToOne
>>> @JoinColumn(name = "PARENT", referencedColumnName = "id", table =
>>> "RegistryObject", nullable = false)
>>> private String parent;
>>>
>>> ...
>>> }
>>>
> ...
>
>