Now everything is pretty clear about ROP client classes. But what
algorithm should we use for server classes UID generation? Suppose it
probably must be somehow related with CayenneDataObject class version...
On 10/04/2011 11:25 AM, Andrus Adamchik wrote:
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