Thanks for your reply Gordon,
my question really is how do I change my code to use
@EmbeddedId AddressPK
instead of @IdClass(AddressPK) and 2 @Id's for the two key elements ?
Of course, I would like to maintain the relationship to Person.
Is that feasible ?
The code as I posted it deploys fine but I keep getting complaints about
multiple writable instances of one key element (ADDRESS.GID) when trying
to use @EmbeddedId - even though I do specify (insertable=false,
updatable=false).
(I thought b32f was pretty recent as it was released in early Feb or
should I rather use b36 ?)
The reason I would like to use @EmbeddedId is that I would like to use a
Map<AddressPK,Address> in Person (instead of a Collection<Address>) to
hold the addresses, so I could use @MapKey<AddressPK> on the Person
side.....
or could I still use it even though AddressPK is not declared as
@EmbeddedId ?
Unfortunaly the example you refer to also uses @IdClass and mupltiple
@Id's rather than @EmbeddedId....
On Di, Februar 14, 2006 16:04, Gordon Yorke wrote:
> This may be an issue with using an older Glassfish build. The classes you
> have attached below should deploy successfully.
>
> In the Glassfish entity-persistence-tests module
> oracle/toplink/essentials/testing/models/cmp3/advanced package you can see
> an example similar to yours using Employee and PhoneNumber where
> PhoneNumber has a compound Primary Key a component of which is a foreign
> key to Employee.
>
> --Gordon
>
> -----Original Message-----
> From: Jochen Seifarth [mailto:js_at_agentbob.info]
> Sent: Tuesday, February 14, 2006 8:01 AM
> To: persistence_at_glassfish.dev.java.net
> Subject: Foreign key as part of compound key and one-to-many
> relationship
>
>
> (Apologies as this is a cross-post from the forum but this seems to be the
> more appropriate place.)
>
> Can anybody help with my problem described below ? Is this due to:
> a) my ignorance being new to EJB persistence
> b) a limitation of JSR-220
> c) a problem in the Glassfish build (b32f) I am using
>
> Trying out EJB3 persistence on Glassfish I have come across the following
> problem:
>
> In a one-to-many relationship, one Person with many Addresses (e.g. home,
> work, etc.), I would like to use the primary key of Person (gid) as part
> of the compound key for Address (gid, aid).
> So, I define an @Embeddable AddressPK class to hold the compound key (gid,
> aid), use this class as @IdClass on @Entity Address and define @Id gid and
> @Id aid.
> So far so good, however, according to my understanding of the spec (=JSR
> 220, proposed final draft) I should also be able to specify @EmbeddedId
> AddressPK on @Entity Address, which to my mind is cleaner as it avoids
> duplication of columns where the names have to match. Using @EmbeddedId
> AddressPK works fine as long as I am not trying to map @ManyToOne to
> Person.
> I tried various approaches:
> -Mapping @ManyToOne from Address, specifying to @JoinColumn(name="GID"):
> Glassfish (actually Oracle Toplink) keeps complaining about multiple
> writeable instances of GID, even though I had set them to
> (insertable=false, updatable=false), both in @Column and @JoinColumn, in
> either and in various other combinations....
> -Trying to map @ManyToOne from AddressPK fails as Toplink complains that
> AddressPK is not an entity....
>
> OK, maybe the spec just doesn't cater for such cases as it refers to such
> compound keys as coming from 'legacy' systems several times. On the other
> hand, from a database perspective there are pretty good reasons for such
> keys and relationships. Also, from a business point of view compound keys
> make a lot of sense.
>
> The next thing I was trying to archieve is to hold the Addresses in Person
> in a Map<AddressPK,Address>, rather than in a Collection<Address> to allow
> me to access items directly by key rather than having to search the whole
> Collection for it. @MapKey should achieve this.... but if I cannot get
> AddressPK to be the @EmbeddedId for Address, what would @MapKey use as the
> key ? .....
>
> Here is my code - I would really appreciate if anybody could show me how
> to change it to use AddressPK as @EmbeddedId while maintaining the
> bidirectional relationship with Person.
>
>
> @Embeddable
> public class AddressPK implements Serializable {
> private String gid;
> private String aid;
>
> public AddressPK() {
> this("", "");
> }
>
> public AddressPK(String gid, String aid) {
> this.gid = gid;
> this.aid = aid;
> }
>
> public boolean equals(AddressPK anotherPK) {
> return (this.gid.equals(anotherPK.gid) && this.aid
> .equals(anotherPK.aid));
> }
>
> public int hashCode() {
> return gid.concat(aid).hashCode();
> }
>
> public String getGid() {
> return gid;
> }
> public void setGid(String gid) {
> this.gid = gid;
> }
>
> public String getAid() {
> return aid;
> }
>
> public void setAid(String aid) {
> this.aid = aid;
> }
> }
>
> ----------------------------------------------------------
>
> @Entity
> @IdClass(AddressPK.class)
> public class Address implements Serializable {
> private AddressPK pk;
> private Person person;
> private String street;
>
> public Address() {
> this(new AddressPK());
> }
>
> public Address(AddressPK pk) {
> this.pk = pk;
> street = "";
> }
>
> public boolean equals(Address another) {
> return (this.pk.equals(another.pk));
> }
>
> public int hashCode(){
> return pk.hashCode();
> }
>
> @Id
> @Column(insertable=false,updatable=false)
> public String getGid() {
> return pk.getGid();
> }
>
> public void setGid(String gid) {
> this.pk.setGid(gid);
> }
>
> @Id
> public String getAid() {
> return pk.getAid();
> }
>
> public void setAid(String aid) {
> this.pk.setAid(aid);
> }
>
> @ManyToOne
> @JoinColumn(name="GID")
> public Person getPerson() {
> return person;
> }
>
> public void setPerson(Person person) {
> this.person = person;
> this.pk.setGid(person.getGid());
> }
>
> public String getStreet() {
> return street;
> }
>
> public void setStreet(String street) {
> this.street = street;
> }
>
> @Transient
> public AddressPK getPk() {
> return pk;
> }
> }
>
> -----------------------------------------------------------
>
> @Entity
> public class Person implements Serializable {
> private String gid;
> private String name;
> private Collection<Address> addresses;
>
> public Person() {
> this("");
> }
>
> public Person(String gid) {
> this.gid = gid;
> }
>
> @Id
> public String getGid() {
> return gid;
> }
>
> public void setGid(String gid) {
> this.gid = gid;
> }
>
> @OneToMany(mappedBy = "person", fetch = FetchType.LAZY)
> public Collection<Address> getAddresses() {
> return addresses;
> }
>
> public void setAddresses(Collection<Address> addresses) {
> this.addresses = addresses;
> }
>
> public String getName() {
> return name;
> }
>
> public void setName(String name) {
> this.name = name;
> }
> }
>
>
>
>
>
>