@Stephen: the sole responsibility of compareTo is to provide a natural ordering based on comparing the values of it's own members against another object of the same type. If you have ordering requirements beyond that scope I suggest you add an order clause to the JDOQL query or use Guava's Ordering [1] .
@Dan: Personally I prefer using Guava's ComparisonChain since ObjectContracts is not typesafe. [1] https://github.com/google/guava/wiki/OrderingExplained On 26 November 2015 at 12:08, Dan Haywood <[email protected]> wrote: > Only time I've seen these sorts of index issues is when the enhancer didn't > run correctly over the entire codebase. > > With respect to compareTo implementations, in Estatio we've got away with > using the ObjectContracts.compareTo method. So, for example, in LeaseItem, > whose parent is Lease and which is also identified by the leaseType and > sequence, the implementation is just > > ObjectContracts.compareTo(this, other, "lease", "type", sequence); > > For your Participation entity I would imagine that using > > ObjectContracts.compareTo(this, other, "activity", "participant"); > > would work. As I think you allude to, it could end up resolving more data > than is necessary, though, in order to do the comparisons of Activity and > then Participant within. > > ~~~ > If you wanted faster comparisons, you could denormalize by holding the key > fields from the Activity and Participant within Participation. For > example, if Activity is comparable on "name", and Participant on > "firstName", "lastName" (say), then the Participation entity could define > "activityName", "participantFirstName", "participantLastName". Then the > comparison of Participation will just use data that's already in memory. > > Of course, that introduces a related problem of maintaining these derived > properties, but for that I would use domain events or lifecycle events. > > Alternatively, yes, you could sort by exposing the database Id of the > Activity and Participant, though I think you'd still need to derive them > down into Participation (I don't know of any way to actually surface the > implied foreign key columns into the domain entity). Perhaps even easier > is to grab the Isis OID (which is derived ultimately from the database Id) > and store that, using the BookmarkService: > > Participant p = ...; > Bookmark participantBookmark = bookmarkService.bookmarkFor(p); > setParticipantId(participantBookmark.toString()); > > > > HTH > Dan > > > > > > > > > On 26 November 2015 at 10:46, Stephen Cameron <[email protected]> > wrote: > > > Hi, > > > > I am trying to improve the compareTo() functions that I have written and > > ran into the following error. > > > > > > - java.lang.ArrayIndexOutOfBoundsException > > - 31 > > - > > > org.datanucleus.state.StateManagerImpl#isLoaded(StateManagerImpl.java:2893) > > > > - > > > au.com.scds.chats.dom.module.activity.RecurringActivity#getStartDateTime(RecurringActivity.java:-1) > > > > - sun.reflect.GeneratedMethodAccessor75#invoke(null:-1) > > - > > > sun.reflect.DelegatingMethodAccessorImpl#invoke(DelegatingMethodAccessorImpl.java:43) > > > > - java.lang.reflect.Method#invoke(Method.java:497) > > - > > org.apache.isis.applib.util.Clause#getValueOf(ObjectContracts.java:365) > > > > - > > > org.apache.isis.applib.util.ObjectContracts#compare(ObjectContracts.java:70) > > > > - > > > org.apache.isis.applib.util.ObjectContracts#compare(ObjectContracts.java:63) > > > > - > > > au.com.scds.chats.dom.module.activity.Activity#compareTo(Activity.java:120) > > > > - > > > au.com.scds.chats.dom.module.activity.Activity#compareTo(Activity.java:54) > > > > - > > > com.google.common.collect.ComparisonChain$1#compare(ComparisonChain.java:76) > > > > - > > > au.com.scds.chats.dom.module.participant.Participation#compareTo(Participation.java:206) > > > > - > > > au.com.scds.chats.dom.module.participant.Participation#compareTo(Participation.java:31) > > > > - java.util.TreeMap#compare(TreeMap.java:1290) > > - java.util.TreeMap#put(TreeMap.java:538) > > - java.util.TreeSet#add(TreeSet.java:255) > > - > > > org.datanucleus.store.types.wrappers.backed.SortedSet#loadFromStore(SortedSet.java:283) > > > > - > > > org.datanucleus.store.types.wrappers.backed.SortedSet#iterator(SortedSet.java:477) > > > > - > > > com.google.common.collect.Collections2$TransformedCollection#iterator(Collections2.java:269) > > > > - > > > org.apache.isis.core.metamodel.facets.collections.CollectionFacetAbstract#iterator(CollectionFacetAbstract.java:46) > > > > - > > > org.apache.isis.core.metamodel.facets.collections.CollectionFacetAbstract$1#iterator(CollectionFacetAbstract.java:54) > > > > - > > > org.apache.isis.core.metamodel.adapter.ObjectAdapter$Util#visibleAdapters(ObjectAdapter.java:314) > > > > - > > > org.apache.isis.core.metamodel.adapter.ObjectAdapter$Util#visibleAdapters(ObjectAdapter.java:302) > > > > - > > > org.apache.isis.core.metamodel.facets.collections.accessor.CollectionAccessorFacetViaAccessor#getProperty(CollectionAccessorFacetViaAccessor.java:85) > > > > - > > > org.apache.isis.core.metamodel.specloader.specimpl.OneToManyAssociationDefault#get(OneToManyAssociationDefault.java:161) > > > > > > I have the comparison for Activity now of startDateTime then name then > > region, so the comparison of Participations (a link table between > Activity > > and Participant) is of Activity first and then Participant. This gets > quite > > complex in terms of retrieving value graphs which might explain the > error. > > > > Is there a better way, maybe I can use database id instead as they > reflect > > order of creation of records, which might be good enough for > participation > > sorting. I've tried to avoid using generated ID values in OO code but > maybe > > its a compromise I have to accept occassionally, instead of natural keys. > > > > Just raising it for discussion. > > > > Thanks > > >
