Hello Oscar. Thank you so much for the detailed examples, as Dan also did, which helped a lot. After reading Dan's comments and yours, I realize that, in fact, the ItemVendor relationship (and some other similar relationships) would have eventually life on its own, with some other properties, so in this case I will keep it as an Entity. I am using some code quite alike the VendorItem sample you included here, and it works now using one of Dan's suggestion to use both item and vendor properties when calling compareTo within ItemVendor. Dan said that this might be not the best solution for performance purposes, so I might keep the additional ItemVendorId field hidden and auto populated with some code, unless there is a way to use the id that is auto generated by JDO annotation (idGeneratorStrategy.IDENTITY column = "id") in the compareTo method call, but I guess this id field might not be visible to Apache ISIS but only to JDO and the database.
I also will keep in mind your other suggestion in case some relationship does not need to be an Entity, so JDO manages it automatically as per your nice example here. Thank you both so much! -----Original Message----- From: Óscar Bou - GOVERTIS [mailto:[email protected]] Sent: Friday, October 9, 2015 7:17 AM To: [email protected] Subject: Re: Apache ISIS relationships Hi again, Cesar. Reading again your post, seems you’ve explicitly modeled the vendor-item m:n relationship, introducing a new VendorItem entity. That would not be needed if using m:n relationships. You directly reference the other Entity on each SortedSet (if they’re bi-directional). You could have something like: public class Vendor { // {{ Items (Collection) @Persistent(table = "Vendor_Item") @Join(column = "Vendor") @Element(column = "Item") private SortedSet<Item> items = new TreeSet<Item>(); public SortedSet<Item> getItems() { return items; } public void setItems( final SortedSet<Item> items) { this.items = items; } // }} } public class Item { // {{ Vendors (Collection) @Persistent(mappedBy = "items") private SortedSet<Vendor> vendors = new TreeSet<Vendor>(); public SortedSet<Vendor> getVendors() { return vendors; } public void setVendors( final SortedSet<Vendor> vendors) { this.vendors = vendors; } // }} } As the SortedSets contain “Vendor” and “Item” entities, I assume they already implement the Comparable interface. If you introduce the VendorItem entity, it can be persisted by DN using Foreign Keys if defined as follows: public class Vendor { // {{ SoldItems (Collection) @Persistent(mappedBy = "vendor", dependentElement = "true") private SortedSet<VendorItem> soldItems = new TreeSet<VendorItem>(); public SortedSet<VendorItem> getSoldItems() { return soldItems; } public void setSoldItems( final SortedSet<VendorItem> soldItems) { this.soldItems = soldItems; } // }} } public class Item { // {{ SoldByVendors (Collection) @Persistent(mappedBy = "item", dependentElement = "true") private SortedSet<VendorItem> soldByVendors = new TreeSet<VendorItem>(); public SortedSet<VendorItem> getSoldByVendors() { return soldByVendors; } public void setSoldByVendors( final SortedSet<VendorItem> soldByVendors) { this.soldByVendors = soldByVendors; } // }} } Please, notice in previous example I’ve called the properties “soldItems” and “soldByVendors”, as they’re returning “VendorItem” and not “Vendor” or “Item” entities. So it’s a new Entity introduce, that might be named properly (perhaps “SoldItem” or similar?). As the relationship has been explicitly modeled as a new Entity (perhaps with its properties and domain logic associated), it needs to implement Comparable. You also told don’t want foreign keys. DataNucleus also allows you to model the previous case with Join tables something like this (despite I’ve never used it. We always use Foreign Keys): public class Vendor { // {{ Item (Collection) @Persistent(mappedBy = "vendor", dependentElement = "true") @Join private SortedSet<Item> items = new TreeSet<Item>(); public SortedSet<Item> getItem() { return items; } public void setItem( final SortedSet<Item> items) { this.items = items; } // }} } HTH, Oscar > El 9 oct 2015, a las 9:55, Óscar Bou - GOVERTIS <[email protected]> escribió: > > > Hi Cesar. > > As Dan points out, m:n relationships are only useful when the "link" does not > have associated attributes or domain logic associated. > We have use cases similar to yours. Many times there's a hidden "entity" > there with its own meaning, and just sometimes we simply model it as an m:n > relationship. > > HTH, > > Oscar > > >> El 9 oct 2015, a las 1:38, Cesar Lugo <[email protected]> escribió: >> >> Hi Dan, >> >> First of all ... Wow! is this not only the fastest Domain Driven development >> framework , but also the one with the quickest response support team? :) >> Second, I am honored to get a response from you, I have read a lot about >> your great work and commitment to Apache ISIS and Naked Objects, and >> excellent tutorials, demos and add-ons. Congratulations! >> >> So I will work on your suggestions and let you know. Thank you so much! >> >> Cesar. >> >> -----Original Message----- >> From: Dan Haywood [mailto:[email protected]] >> Sent: Thursday, October 8, 2015 5:58 PM >> To: users >> Subject: Re: Apache ISIS relationships >> >> Hi Cesar, >> >> and welcome to [email protected] mailing list. >> >> A few thoughts on this... >> >> ... first suggestion: you ought to be able to map this relationship as an >> m:n, rather than as two 1:m and n:1 relationships. I must admit I don't >> do that in Estatio, but Oscar has done it I believe, because he included the >> m:n relationship in the set of templates he developed for IntelliJ / Eclipse >> [1]. I think the ones you want are called "iscs.jdo.mn.ub.p" (Isis JDO m:n >> parent) and ""iscs.jdo.mn.ub.c" (Isis JDO m:n child). >> >> There's also info on m:n relationships at the Datanucleus site [2]. So far >> as possible Isis isn't responsible for persistence, that is delegated to >> DataNucleus ... so if it's a feature of DN then it *should* "just work" in >> Isis. >> >> >> ... second suggestion: if you do decide to have a link item table, >> then you could use the foreign references to Vendor and to Item, eg >> ObjectContracts.compareTo(this, "vendor", "item"). I'm not sure I >> recommend this, though, because it will require the referenced >> objects to be loaded in order to do a comparison, which could impact >> performance >> >> >> ... third suggestion: do a bit more domain modelling. I suspect that, over >> time, you will find attributes/responsibilities that live on the link >> entity, and it probably has a more meaningful name than just "VendorItem". >> If it represents the fact that a vendor can sell an item, then presumably it >> has a cost, and perhaps a discount, and maybe a target profitability, and >> perhaps a wholesale supplier from which the vendor purchases it in turn. >> This is the reason we have no m:n relationships in Estatio ... >> there's almost always something interesting to say about that relationship. >> >> HTH, >> >> Dan >> >> >> >> [1] http://isis.apache.org/guides/cg.html#_cg_ide-templates >> [2] >> http://www.datanucleus.org/products/accessplatform/jdo/orm/many_to_ma >> ny.html >> >> >> >> >>> On 8 October 2015 at 23:27, Cesar Lugo <[email protected]> wrote: >>> >>> Hello again! >>> >>> >>> >>> I have created an Apache ISIS prototype application, and in some >>> cases I need to have some Domain Entities that do not have any >>> properties other than references to other Domain Entities, for >>> example, used just to build Many-to-Many relationships among 2 >>> Domain Entities (I am not using foreign keys). For example, a Vendor >>> can sell us many Items, and an Item can be purchased by many >>> Vendors. So I define a VendorItem entity, which has a property to >>> reference Item and Vendor entities within it. Everything works fine, >>> until I get to the collections (using SortedSet) on Item and on >>> Vendor to list all VendorItem relationships either from Item or from >>> Vendor. In that case, because VendorItem needs to be implemented >>> using a Comparable class, it requires a field for the CompareTo >>> method. The only way I have been able to work around it is to >>> declare a property (vendorItemId) that I don't really need, and >>> populate it manually every time I create a new VendorItem >>> relationship. Is there a way to avoid using such a >>> (vendorItemId) >>> property, or use the automatic "id" field generated by the JPO >>> idGeneratorStrategy.IDENTITY column = "id" annotation?. Or, is there >>> any other better way to manage Many-To-Many relationships using >>> Apache ISIS and JPO? >>> >>> >>> >>> Cesar. >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> --- >>> This email has been checked for viruses by Avast antivirus software. >>> https://www.avast.com/antivirus >> >> >> --- >> This email has been checked for viruses by Avast antivirus software. >> https://www.avast.com/antivirus >> --- This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus
