Actually... since CayenneDataObject is a Map, do we even care about attributes and relationships? No matter what they are, serialization format should stay the same..
Now we also have ROP where objects are NOT maps. So we need a different algorithm for those , which is more like the one you implemented (+ my suggestion about relationship type ... for to-one) That means that we need 2 different algorithms used in server and ROP templates. Andrus On Oct 4, 2011, at 11:19 AM, Andrus Adamchik wrote: > Very cool. > > Can we also create some unit tests for this to ensure it works as advertised. > E.g. a possible caveat is consistent alphabetic ordering of relationships and > attributes (IIRC they are ordered by default, but it is worth creating some > tests to see how entity creation affects the result). Also I think in > relationships loop we may add a check for the target entity type. > > Andrus > > > > On Oct 4, 2011, at 11:10 AM, Dzmitry Kazimirchyk wrote: > >> Just committed fix to the trunk (r1178712). UID generation algorithm uses >> same approach as java.io.ObjectStreamClass.getSerialVersionUID(). Generated >> id depends on ObjEntity's superclass, ObjAttributes and ObjRelationships >> names and types. >> >> Here is the diff: >> >> Modified: >> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/ObjEntity.java >> URL:http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/ObjEntity.java?rev=1178712&r1=1178711&r2=1178712&view=diff >> ============================================================================== >> --- >> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/ObjEntity.java >> (original) >> +++ >> cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/ObjEntity.java >> Tue Oct 4 07:57:40 2011 >> @@ -19,6 +19,9 @@ >> >> package org.apache.cayenne.map; >> >> +import java.io.ByteArrayOutputStream; >> +import java.io.DataOutputStream; >> +import java.security.MessageDigest; >> import java.util.ArrayList; >> import java.util.Arrays; >> import java.util.Collection; >> @@ -1250,5 +1253,42 @@ public class ObjEntity extends Entity im >> public void setExcludingSuperclassListeners(boolean >> excludingSuperclassListeners) { >> this.excludingSuperclassListeners = excludingSuperclassListeners; >> } >> + >> + /** >> + * Returns unique id for this ObjEntity. >> + * >> + * @since 3.1 >> + */ >> + public long getSerialVersionUID() throws Exception { >> + ByteArrayOutputStream bout = new ByteArrayOutputStream(); >> + DataOutputStream dout = new DataOutputStream(bout); >> + >> + dout.writeUTF(getClassName()); >> + >> + if (getSuperClassName() != null) { >> + dout.writeUTF(getSuperClassName()); >> + } >> + >> + for (ObjAttribute attr : getAttributes()) { >> + dout.writeUTF(attr.getName()); >> + dout.writeUTF(attr.getType()); >> + } >> + >> + for (ObjRelationship rel : getRelationships()) { >> + dout.writeUTF(rel.getName()); >> + dout.writeUTF(rel.getCollectionType() != null >> + ? rel.getCollectionType() : "to-one"); >> + } >> + >> + dout.flush(); >> + >> + MessageDigest md = MessageDigest.getInstance("SHA"); >> + byte[] hashBytes = md.digest(bout.toByteArray()); >> + long hash = 0; >> + for (int i = Math.min(hashBytes.length, 8) - 1; i>= 0; i--) { >> + hash = (hash<< 8) | (hashBytes[i]& 0xFF); >> + } >> + return hash; >> + } >> >> } >> >> >> Dzmitry >> >> On 10/04/2011 08:22 AM, Andrus Adamchik wrote: >>> +1. We had a brief discussion with Dzmitry to that extent last night. Here >>> is an extract from that chat: >>> >>>> Generated classes (the ones with _XXX) are made from ObjEntities, so if we >>>> can use an alg. based on ObjEntity state, I think that should be enough >>>> just need to account for all its parts (superclass, objattribute names and >>>> types; objrelationship names and types) >>> So yeah, IMO it does have to be like hashcode of sorts based on ObjEntity >>> state... >>> >>> Andrus >>> >>> On Oct 4, 2011, at 2:53 AM, Mike Kienenberger wrote: >>> >>>> No, it should be more clever than that. Otherwise, every time you >>>> regenerate the template, the generated code will change even if >>>> nothing else had changed. That will also break serialization. >>>> >>>> Ideally, it should return the same number whenever the same fields and >>>> types are used for the generated class. >>>> >>>> Maybe build the number by iterating over the attributes and >>>> relationships and feeding it into >>>> org.apache.commons.lang.builder.HashCodeBuilder, basing it on the >>>> order and type >>>> >>>> >>>> On Mon, Oct 3, 2011 at 7:41 PM, Ari Maniatis (Commented) (JIRA) >>>> <[email protected]> wrote: >>>>> [ >>>>> https://issues.apache.org/jira/browse/CAY-1622?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13119757#comment-13119757 >>>>> ] >>>>> >>>>> Ari Maniatis commented on CAY-1622: >>>>> ----------------------------------- >>>>> >>>>> Do we just want to add this to the velocity templates: >>>>> >>>>> private static final long serialVersionUID = >>>>> ${random(1,9223372036854775807)}; >>>>> >>>>>> Generated classes shouldn't produce serialVersionUID compiler warning >>>>>> --------------------------------------------------------------------- >>>>>> >>>>>> Key: CAY-1622 >>>>>> URL: https://issues.apache.org/jira/browse/CAY-1622 >>>>>> Project: Cayenne >>>>>> Issue Type: Bug >>>>>> Components: Core Library >>>>>> Affects Versions: 3.0 >>>>>> Reporter: Bob Harner >>>>>> Priority: Minor >>>>>> >>>>>> It is probably a good idea for Cayenne not to produce any compiler >>>>>> warnings, but auto-generated entity classes always have the "The >>>>>> serializable class _Foo does not declare a static final serialVersionUID >>>>>> field of type long" compiler warning. >>>>>> The @SuppressWarnings("serial") annotation will get rid of the warnings, >>>>>> but of course it is not recommended to manually update the generated >>>>>> classes. >>>>>> Users could configure the IDE to ignore these warnings (yuk), but then >>>>>> other team members will still see them. >>>>>> Another option is to for users to set up a custom velocity template to >>>>>> include this annotation. >>>>>> But the best solution would be for Cayenne to either automatically >>>>>> generate either the serialVersionUID itself or the >>>>>> @SuppressWarnings("serial") annotation that suppresses the compiler >>>>>> warning. >>>>> -- >>>>> This message is automatically generated by JIRA. >>>>> If you think it was sent incorrectly, please contact your JIRA >>>>> administrators: >>>>> https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa >>>>> For more information on JIRA, see: http://www.atlassian.com/software/jira >>>>> >>>>> >>>>> >> >> > >
