persistence@glassfish.java.net

Re: Problem using ManyToMany relationship

From: Marina Vatkina <Marina.Vatkina_at_Sun.COM>
Date: Wed, 28 Mar 2007 13:01:45 -0700

Tim,

All annotations should be placed in a similar way - either on the fields or on
the properties (i.e. getters). The current spec doesn't allow to mix them not
only in the same class, but even in an inheritance hierarchy.

Why do you need to use @AttributeOverride? Here is what the spec says:

9.1.10 AttributeOverride Annotation

The AttributeOverride annotation is used to override the mapping of a Basic
(whether explicit or default) property or field or Id property or field. The
AttributeOverride annotation may be applied to an entity that extends a mapped
superclass or to an embedded field or property to override a basic mapping
defined by the mapped superclass or embeddable class.

Regards,
-marina

Romanowski, Tim wrote:
> 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…@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
>
>
>
>
>