Return-Path: Delivered-To: apmail-openjpa-users-archive@locus.apache.org Received: (qmail 7958 invoked from network); 11 Jan 2008 14:26:51 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 11 Jan 2008 14:26:51 -0000 Received: (qmail 29024 invoked by uid 500); 11 Jan 2008 14:26:41 -0000 Delivered-To: apmail-openjpa-users-archive@openjpa.apache.org Received: (qmail 28894 invoked by uid 500); 11 Jan 2008 14:26:41 -0000 Mailing-List: contact users-help@openjpa.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: users@openjpa.apache.org Delivered-To: mailing list users@openjpa.apache.org Received: (qmail 28885 invoked by uid 99); 11 Jan 2008 14:26:41 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 11 Jan 2008 06:26:41 -0800 X-ASF-Spam-Status: No, hits=2.2 required=10.0 tests=HTML_MESSAGE,SPF_PASS,WHOIS_MYPRIVREG X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: domain of saintx.opensource@gmail.com designates 66.249.82.239 as permitted sender) Received: from [66.249.82.239] (HELO wx-out-0506.google.com) (66.249.82.239) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 11 Jan 2008 14:26:14 +0000 Received: by wx-out-0506.google.com with SMTP id s7so693717wxc.24 for ; Fri, 11 Jan 2008 06:26:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from:to:subject:in-reply-to:mime-version:content-type:references; bh=SFw66v7L8BrxXtmJOp4VCfvFRz7oBz4wR3e4HNVSAwM=; b=GtBCydr6pc1CkVKvtZd+oaaHvPpIH6Caok4ExE7ixP2rA7vZzQHRZjK3Ltx//ikdYaPtWr8aWzzOnnyy4Z7Mfnl7+3y6T8Tz/XKu0qBQXp5d1HDVAeRvb3na8FJGUaRBwpF+qoXOLPtck0wqXq1O/EqVhy/iCG3cgc6YlTgODDM= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:to:subject:in-reply-to:mime-version:content-type:references; b=wBYvtreF3v6VWmVtEIA/x7RYIZpOX2OVCrQ0p2EBU3f7DwdoyAoY6xOHK+BP01Q1TBg/iPlJn7ZzmcaWGRrZvl/1Z+xCq9LOnDW9jd56dGdJkxpE8DCIse5BJ4d/rhfquKZ/uu8n++lxq8h86vIITYPpheEsezXOJkC6MFJDnuU= Received: by 10.150.135.2 with SMTP id i2mr1357429ybd.127.1200061576407; Fri, 11 Jan 2008 06:26:16 -0800 (PST) Received: by 10.151.12.4 with HTTP; Fri, 11 Jan 2008 06:26:16 -0800 (PST) Message-ID: Date: Fri, 11 Jan 2008 08:26:16 -0600 From: "Alexander Saint Croix" To: users@openjpa.apache.org Subject: Re: Using a Maps instead of Sets to handle @ManyToMany? In-Reply-To: <14743250.post@talk.nabble.com> MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_Part_583_6927519.1200061576397" References: <14743250.post@talk.nabble.com> X-Virus-Checked: Checked by ClamAV on apache.org ------=_Part_583_6927519.1200061576397 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline Cedric, I might be able to help you with this. I just got done implementing this in my Open Source CORM project, for which the corm-party library is undergoing CRUD and cascade testing. There is an @MapKey annotation outlined near the bottom of the EJB 3.0Persistence specification that should shed some light on your problem--did for me. There is also a proprietary @PersistentMap annotation that (I believe) OpenJPA provides. You'll have to continue to inquire about that. I didn't end up using either of these solutions. For my part, I ended up implementing Property and PropertyKey classes, and an association class, AssociatedAddress, to bridge the gap between Address and Party. Since addresses can be associated with numerous parties and parties can have numerous addresses, it's inevitable that there'll be an association table anyway, but since address_party associations are important enough to warrant having their own metadata, I created a class that has a reference to Party, one to Address, and a set of Property objects. Each property has one PropertyKey (with its own String 'name') and one String 'value', for normalization purposes (chances are this'll get further refactored before it's done). I owe the idea for this to Roger Mori, a good acquaintence of mine. After looking at the Map persistence options, and after considering long-term normalization problems, I felt it was better to implement my own property tables for association metadata. I now use it in a handful of other locations throughout the project. On Jan 10, 2008 2:43 PM, Cedric Hurst wrote: > > I have a domain model which can be simplified as follows: > > // AddressType.java > > public enum AddressType implements java.io.Serializable { > BILLING, > SHIPPING; > } > > // Address.java > > import javax.persistence.*; > import java.util.*; > > @Entity > public class Address implements java.io.Serializable { > @Id @GeneratedValue > public long Id; > public String street, city, state, zip; > @Enumerated(EnumType.STRING) > public AddressType addressType; > > @ManyToMany(mappedBy="addresses") > public Set customers; > } > > //Customer.java > > import javax.persistence.*; > import java.util.*; > > @Entity > public class Customer implements java.io.Serializable { > @Id @GeneratedValue > public long Id; > public String name; > > @ManyToMany > Set
addresses; > } > > Intuitively, though, AddressType is more relevant to the relationship > *between* Customer and Address, not solely Address. The same Address > could > have multiple AddressTypes depending on which Customer you're talking > about > (for instance, if I have my office address listed as my personal SHIPPING > address but my employer is also a distinct Customer who uses the same > address for its BILLING). > > Of course, the most obvious solution would be to explicitly define the > associative entity as a proper domain class: > > // CustomerAddress.java > > import javax.persistence.*; > > @Entity > public class CustomerAddress implements java.io.Serializable { > @Id @GeneratedValue > public long Id; > public Customer customer; > public Address address; > public AddressType addressType; > } > > > ... but then I lose all the advantages of JPA to handle the many-to-many > relationship. > > Ideally, I'd like to do something like this: > > // Address.java > > import javax.persistence.*; > import java.util.*; > > @Entity > public class Address implements java.io.Serializable { > @Id @GeneratedValue > public long Id; > public String street, city, state, zip; > @Enumerated(EnumType.STRING) > public AddressType addressType; > > @ManyToMany(mappedBy="addresses") > public Map> customers; > } > > //Customer.java > > import javax.persistence.*; > import java.util.*; > > @Entity > public class Customer implements java.io.Serializable { > @Id @GeneratedValue > public long Id; > public String name; > > @ManyToMany > Map> addresses; > } > > > As you can see, this pattern would allow me to look up all the Addresses > of > a certain AddressType directly from the Customer class. It would also > allow > me to lookup all the AddressTypes associated with a particular Customer > directly from the Address class. But it doesn't seem to be covered in the > general JPA spec, and OpenJPA treats the Map as a BLOB. Off in SQL-land, > it's very common to add lookup-table references to associate entities. It > seems like there should be a way to do accommodate this in JPA without > creating a new class. Any suggestions? > -- > View this message in context: > http://www.nabble.com/Using-a-Maps-instead-of-Sets-to-handle-%40ManyToMany--tp14743250p14743250.html > Sent from the OpenJPA Users mailing list archive at Nabble.com. > > ------=_Part_583_6927519.1200061576397--