I think I may have found OpenJPA's solution to this problem. Could someone comment? Thanks!

http://openjpa.apache.org/docs/latest/manual/manual.html#ref_guide_mapping_jpa_onemany

@Entity
public class Node
{
  @Id
  protected long id;

  @OneToMany
  @ElementJoinColumn(name="parent_id", target="id")
  protected Collection<Node> children;
}

Andy Schlaikjer wrote:
I think it's not wonderful that you have to add an extra field to your object model if you're really not interested in modeling the ManyToOne side of a relationship like this. However, at the moment you can't "reuse" a single table to map both an entity and a join table, so we're stuck.

For example, this doesn't work:

@Entity
public class Node
{
  @Id
  protected long id;

  @OneToMany()
  @JoinTable(
    name = "Node",
    joinColumns = @JoinColumn(name = "parent_id"), // i wish
    inverseJoinColumns = @JoinColumn(name = "id")
  )
  protected Collection<Node> children;

  ...
}

Michael Vorburger wrote:
Hello,

Similar situation here, and I wonder about people's thoughts & pros/cons
regarding this:

Your solution (anotate "ModelObject parent;" with @ManyToOne instead
of @Transient and add mappedBy="parent" to @OneToMany) works, also for
my application, but turns the uni-directional relation into a
bi-directional relation.  And this bi-directional relation is more
dificult to manage and not needed in our Java application.

Why is this "bi-directional relation is more dificult to manage and not
needed in our Java application" ?  If you let OpenJPA deal with this for
you with the Managed Inverses
(http://openjpa.apache.org/docs/latest/manual/ref_guide_inverses.html),
what's the problem with an additional field?  Hide it even - if for some
reason you don't want to expose the bi-directionality to the users of
the object model for keep that '@ManyToOne ModelObject parent' as a
private with no setters and getters - just to get the desired mapping!

What's the issue with this approach?  (Portability and not wanting to
use Managed Inverses aside; but I don't know if that's strong enough,
you're using OpenJPA specific configuration elsewhere already, and
that's really what this is - a runtime configuration specific to one JPA
implementation.  Other implementations may have a similar feature?  If
not, worst case, when switching, manually code the logic [with loop
detection, if needed]).

Regards,
Michael


-----Original Message-----
From: Uden [mailto:[EMAIL PROTECTED] Sent: jeudi, 8. mai 2008 21:37
To: [email protected]
Subject: Re: Question about @OneToMany


Hi Andy, thanks for the quick response.

In my application i had three tables generated (a master, a detail and a
join table) for what i believed could be modelled by just the master and
a detail table (at least in traditional database modeling). So when i
was looking for a solution to simplify my datamodel in the database, i
found this posting which looked similar to my problem and added my
question.
I need to map the following Java classes (note i reuse Marco's code
example):

@MappedSuperclass
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
class ModelObject {

        @Id
        private int id

        @Transient
        ModelObject parent;

        @OneToMany(cascade={CascadeType.ALL}, fetch=FetchType.EAGER)
        List<ModelObject> children;

        .....
}

@Entity
class Company extends ModelObject {
}

@Entity
class Employer extends ModelObject {
}

to the folowing database tables:

COMPANY (ID     (PK)
, ...
)

and EMPLOYEE
(ID     (PK)
,COMPANY_ID    (FK to COMPANY.ID)
, ...
)

In Marco's original question he indicates that in his case "openjpa
create 4 tables (Company, Company_children, Emplpyer and
Employer_children).". Your solution (anotate "ModelObject parent;" with @ManyToOne instead of
@Transient and add mappedBy="parent" to @OneToMany) works, also for my
application, but turns the uni-directional relation into a
bi-directional relation. And this bi-directional relation is more dificult to manage and not
needed in our Java application. It does however results in a simpler
datamodel.
Your second solution changes the direction (or ownership) of the
relation in the Java model.

So it seems we have to trade a simplified database datamodel versus a
simplified Java datamodel.

Or is there an other solution?

thanks,
Uden


hazen wrote:
Hi Uden,

If you'd rather keep the relation unidirectional just remove the `children` field-- the `parent` field alone is enough to encode the relation without recourse to a separate join table. Either way, I don't see how the quoted section below results in a join table. Both fields rely solely on a "parent_id" column within the "ModelObject" table, not on some other join table. Am I missing something?

Andy

Uden wrote:
The solution quoted below but has a consequence for the Java class
model:
the
OneToMany relationship becomes bi-directional instead of
uni-directional.
What is the reason for creating the join-table?
I thought (based on my database experience) that a join-table is only

required for ManyToMany relationships.
If you look at the data in the join-table of a uni-directional relation (no mappedBy attribute), the relation between the join-table

and master table is always OneToOne, so this relation could be handled by a FK-field in the detail-table.

thanks for your explanation,
Uden


Andy Schlaikjer-2 wrote:
Marco Schwarz wrote:
How can I make only 2 tables?
Here's my guess:

First, use the "mappedBy" property of the @OneToMany annotation, like
this:

@Entity
class ModelObject {
   ...

   @ManyToOne
   ModelObject parent;

   @OneToMany(mappedBy="parent")
   List<ModelObject> children;

   ...
}

This way, an extra join table won't be necessary to encode the parent child relationship. Only the "parent_id" column in the
"ModelObject"
table will be used to encode the relationship.



--
View this message in context:
http://www.nabble.com/Question-about-%40OneToMany-tp16840368p17134828.ht
ml
Sent from the OpenJPA Users mailing list archive at Nabble.com.


____________________________________________________________

• This email and any files transmitted with it are CONFIDENTIAL and intended solely for the use of the individual or entity to which they are addressed. • Any unauthorized copying, disclosure, or distribution of the material within
  this email is strictly forbidden.
• Any views or opinions presented within this e-mail are solely those of the
  author and do not necessarily represent those of Odyssey Financial
Technologies SA unless otherwise specifically stated.
• An electronic message is not binding on its sender. Any message referring to
  a binding engagement must be confirmed in writing and duly signed.
• If you have received this email in error, please notify the sender immediately
  and delete the original.


Reply via email to