persistence@glassfish.java.net

RE: Problem using ManyToMany relationship

From: Romanowski, Tim <tim.romanowski_at_lmco.com>
Date: Wed, 28 Mar 2007 14:46:20 -0400

Markus, thanks for the response; hopefully I can provide you enough info to
help me. When you said "Please note that you can't have both field- and
property-based access in the same entity (Your example shows the Id
annotation on the field, and you mention annotating the getter method)", I'm
not sure I understand._at_Id is for my Team entity is on the field "teamid".
The method I annotated (getUserCollection) refers to the userCollection
field, not the teamid field. Is there something I'm not seeing? Perhaps
you are referring to the @Id for the username field in the Users entity? If
so, why does it matter that the getter of Users in another class (Team
entity) is disallowed to have the below annotation? I can't post all the
code in the classes, but I can post most of it; here's the code again,
formatted a little better.

 

My preference is to only annotate fields, not methods, but that failed to
compile for me. I did just now remove the @AttributeOverride and that did
not cause any noticeable issues. Obviously, I'm not sure what I'm doing-I
was following the spec, but had some odd behavior, so I began reading
various web articles and ManyToMany examples.eventually settling on the code
below, which was the only code I found to 'work,' in the sense that it would
at least compile and deploy. Any further comments are fully welcome!

 

 

@Entity

@Table(name = "TEAM")

public class Team implements Serializable {

         

    @SequenceGenerator(sequenceName="seq_teamid", name="teamid_gen",
initialValue=1, allocationSize=1)

         

    @Id @GeneratedValue(generator="teamid_gen")

    @Column(name = "TEAMID", nullable = false)

    private BigDecimal teamid;

 

@ManyToMany

    private java.util.Collection <com.my.persistence.entity.Users>
userCollection;

 

 

   @ManyToMany

   @JoinTable(name = "team_users",

        joinColumns = {_at_JoinColumn(name = "teamid", referencedColumnName =
"teamid")},

        inverseJoinColumns = {_at_JoinColumn(name = "username",
referencedColumnName = "username")})

    public java.util.Collection<com.my.persistence.entity.Users>
getUserCollection() {

        return userCollection;

    }

 

    public void
setUserCollection(java.util.Collection<com.my.persistence.entity.Users>
userCollection) {

        this.userCollection = userCollection;

    }

} // End class Team

 

 

@Entity

@Table(name = "USERS")

public class Users implements Serializable {

 

    @Id

    @Column(name = "USERNAME", nullable = false)

    private String username;

 

    @ManyToMany(mappedBy="userCollection")

    @AttributeOverride(name="teamCollection", column=_at_Column(name="teamid"))

    private java.util.Collection <com.my.persistence.entity.Team>
teamCollection;

 

 

    public java.util.Collection <com.my.persistence.entity.Team>
getTeamCollection() {

        return this.teamCollection;

    }

 

    public void setTeamCollection(java.util.Collection
<com.my.persistence.entity.Team> teamCollection) {

        this.teamCollection = teamCollection;

    }

}

 

 

 

  _____

From: Markus.Fuchs_at_Sun.COM [mailto:Markus.Fuchs_at_Sun.COM]
Sent: Monday, March 26, 2007 5:44 PM
To: persistence_at_glassfish.dev.java.net
Subject: Re: Problem using ManyToMany relationship

 

Hi Tim,

Romanowski, Tim wrote:

Tricky problem I thought I solved, and I hope someone could explain to me
both 1) why this kind of works, and 2) why it doesn't completely work.

 

Situation: I have a ManyToMany relationship between two entities, Team and
User. A team has many users and a user has many teams. I have a join table
called team_users which contains two fields: teamid and username, which map
to the corresponding primary keys of the Team and User tables.

 

Problem: Creating a 'standard' ManyToMany relationship where I pick an
arbitrary owning entity and annotate a member variable (rather than its get
method) does not work. The only way for me to compile and deploy my webapp
is to annotate these two entities as you see below.

 

Questions:

In the Team entity, why doest the @JoinTable annotation on the
getUserCollection method work, but not work if I instead place that same
annotation on the userCollection property?

Both ways should work. Please note that you can't have both field- and
property-based access in the same entity (Your example shows the Id
annotation on the field, and you mention annotating the getter method)



In the User entity, why must I use the @AttributeOverride annotation on the
teamCollection property?

No annotation besides "mappedBy" should be used on the non-owning side. The
AttributeOverwrite must not be used.

Could you please send me your the Team and User classes?

Thanks,

-- markus.



Why does NetBeans report "Inconsistent access type in entity class because a
field in this class or its super class chain is already annotated as @Id or
@EmbeddedId." This error is shown as a red squiggly line under
getUserCollection in the Team entity. BUT.I can still compile and deploy,
and run my app.

 

Would someone please explain to me some of the details with what is going on
here? Perhaps my entire approach is backward?

I am compiling with JDK 1.5.0_11-b3 and running on Glassfish V2 Build 40.
This problem goes back to builds in the mid 20s (when I started using these
entites).

 

 

Team Entity:

<snip/>

    @Id @GeneratedValue(generator="teamid_gen")

    @Column(name = "TEAMID", nullable = false)

    private BigDecimal teamid;

            

<snip> now here's the reference to my collection of User entities. </snip>


    @ManyToMany

    private java.util.Collection <com.my.persistence.entity.Users>
userCollection;

 

 

<snip> and the only way for my code to compile and deploy (despite the NB
error), specifying the getter like so. </snip>

   @ManyToMany

   @JoinTable(name = "team_users",

        joinColumns = {_at_JoinColumn(name = "teamid", referencedColumnName =
"teamid")},

        inverseJoinColumns = {_at_JoinColumn(name = "username",
referencedColumnName = "username")})

    public java.util.Collection<com.my.persistence.entity.Users>
getUserCollection() {

        return userCollection;

    }

 

    public void
setUserCollection(java.util.Collection<com.my.persistence.entity.Users>
userCollection) {

        this.userCollection = userCollection;

    }

 

 

User entity:

            <snip/>

    @Id

    @Column(name = "USERNAME", nullable = false)

    private String username;

 

    @ManyToMany(mappedBy="userCollection")

    @AttributeOverride(name="teamCollection", column=_at_Column(name="teamid"))

    private java.util.Collection <com.my.persistence.entity.Team>
teamCollection;

 

 

<snip> Nothing special is done to the getters and setter for this
(arbitrarily selected) NON-owning side. </snip>

    public java.util.Collection <com.my.persistence.entity.Team>
getTeamCollection() {

        return this.teamCollection;

    }

 

    public void setTeamCollection(java.util.Collection
<com.my.persistence.entity.Team> teamCollection) {

        this.teamCollection = teamCollection;

    }

 

 

Tim