persistence@glassfish.java.net

Re: Recursive relationship

From: Sanjeeb Kumar Sahoo <Sanjeeb.Sahoo_at_Sun.COM>
Date: Thu, 12 Jan 2006 17:28:26 +0530

Martin Adamek wrote:

> Thanks Michael,
>
> that helped, it's working now. I just don't understand why it is needed.


looks like a bug to me. Pl file a bug in issue tracker.

Thanks,
Sahoo

> My understanding was that there should be default applied, isn't it
> clear from the context, which column I want to use? (and it's working
> in Hibernate :-)
>
> Anyway, thanks for help.
> -M
>
> Michael Bouschen wrote:
>
>> Hi Martin,
>>
>> I think the getParent method misses a JoinColumn annotation
>> specifying the foreign key column for the parent-child relationship.
>> I assume the table for the Category entity has a foreign key column
>> e.g. PARENT_ID referring the Id column of the table. Then the
>> annotation could look like:
>> @ManyToOne()
>> @JoinColumn(name="PARENT_ID")
>> public Category getParent() {
>> return parent;
>> }
>>
>> Hope that helps.
>>
>> Regards Michael
>>
>>> Hi all,
>>>
>>> I tried to create entity which can be recursively pointing to
>>> instances of same type. I want to use it for representing product
>>> categories navigation menu:
>>>
>>> - Computers
>>> - Laptops
>>> - Cables
>>> - ...
>>> - Cameras
>>> - Digital
>>> - Cards
>>> - MMC
>>> - SD
>>> - XD
>>> - ...
>>>
>>> Following entity I can use in Hibernate EM in J2SE without problems
>>> but on GlassFish I am experiencing problems on deployment (see below).
>>>
>>> Entity:
>>> ---%<---
>>> package foo.entity;
>>> import java.util.ArrayList;
>>> import java.util.List;
>>> import javax.persistence.*;
>>>
>>> @Entity
>>> public class Category {
>>> private Long id;
>>> private String name;
>>> private Category parent;
>>> private List<Category> children;
>>>
>>> public Category() {
>>> children = new ArrayList();
>>> }
>>>
>>> @Id(generate = GeneratorType.AUTO)
>>> public Long getId() {
>>> return id;
>>> }
>>>
>>> public void setId(Long id) {
>>> this.id = id;
>>> }
>>>
>>> public String getName() {
>>> return name;
>>> }
>>>
>>> public void setName(String name) {
>>> this.name = name;
>>> }
>>>
>>> @ManyToOne()
>>> public Category getParent() {
>>> return parent;
>>> }
>>>
>>> public void setParent(Category parent) {
>>> this.parent = parent;
>>> }
>>>
>>> @OneToMany(mappedBy="parent", cascade={CascadeType.ALL})
>>> public List<Category> getChildren() {
>>> return children;
>>> }
>>>
>>> public void setChildren(List<Category> children) {
>>> this.children = children;
>>> }
>>> }
>>> ---%<---
>>>
>>> GlassFish exceptions:
>>> ---%<---
>>> Exception [TOPLINK-48] (Oracle TopLink Essentials - 10g release 4
>>> (10.1.4.0.0) (Build 051215Dev)):
>>> oracle.toplink.essentials.exceptions.DescriptorException
>>> Exception Description: Multiple writable mappings exist for the
>>> field [CATEGORY.ID]. Only one may be defined as writable, all
>>> others must be specified read-only.
>>> Mapping: oracle.toplink.essentials.mappings.OneToOneMapping[parent]
>>> Descriptor: RelationalDescriptor(foo.entity.Category -->
>>> [DatabaseTable(CATEGORY)])
>>> ---%<---
>>>
>>> Any idea, what's the problem?
>>>
>>> -M
>>