Issue Details (XML | Word | Printable)

Key: GDS-752
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Major Major
Assignee: Franck Wolff
Reporter: Louis S
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
GraniteDS

Entity not reset as null and internal lazy state on the Java side after deserialization

Created: 23/Aug/10 09:20 PM   Updated: 26/Aug/10 03:12 PM   Resolved: 26/Aug/10 03:12 PM
Component/s: AMF3 (de)serialization
Affects Version/s: 2.1.0_GA
Fix Version/s: 2.2.0_RC2


 Description  « Hide
I'm getting the following error after flex passes an
entity back to the server.

Caused by:
org.granite.messaging.amf.io.convert.NoConverterFoundException: Cannot
convert: EA1A6A19-5627-9570-349E-8FCE2E3F82D3 to: class java.lang.Long
        at
org.granite.messaging.amf.io.convert.Converters.getConverter(Converters.java:
119)
.... (see below for full stack trace)

The error seems to occur because the columns are not being properly
aligned during the de-serialization process (from flex to java). In
this instance, the client id is being mapped back to a Long. I notice
if I add/subtract entity columns, the error seems to just shift to
another column.

I spoke with a colleague of mine and he mentioned he had the same
issue and came up with a workaround (see below).

So in my example I have three entities:
1. ReviewPlan
2. Note
3. NoteType

*ReviewPlan consists of 0 or more Notes
*Each Note may have a NoteType

Here is what is happening:
1. Flex client request a ReviewPlan. Java builds a ReviewPlan, which
has two Notes attached. Each Note has its NoteType property set to
Null (no eager fetch is done).
2. Java sends the ReviewPlan to Flex and the ReviewPlan is usable on
the Flex side.
3. On Flex end, I see the ReviewPlan with two Notes (as expected).
But I noticed that rather than each Note's NoteType being set to null
(as expected), granite attached a new NoteType with null values.
4. On the Flex end, save is clicked and the same object graph is
passed back to Java (and the error occurs).

My colleague's workaround was, in this example, to set the NoteType to
null in Flex prior to sending the graph back to Java. Doing this,
seems to correct the issue.

My thought is, if we are both experiencing this issue, it's either a
bug or we're missing something within our configuration. Why is
granite creating a new object for a property that was set to null (on
the Java side)? Any thoughts?

Below are the stack trace, JPA files, their corresponding generated AS
files, and my granite-config.xml.

~~~~
Stack Trace
~~~~

2010-08-20 10:01:48,413 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 84]
readObject()...
2010-08-20 10:01:48,413 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 157]
readAMF3Integer() -> 3
2010-08-20 10:01:48,413 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 103]
readObject(type=0x03)
2010-08-20 10:01:48,413 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 84]
readObject()...
2010-08-20 10:01:48,413 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 157]
readAMF3Integer() -> 6
2010-08-20 10:01:48,413 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 103]
readObject(type=0x06)
2010-08-20 10:01:48,413 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 174]
readAMF3String()...
2010-08-20 10:01:48,413 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 157]
readAMF3Integer() -> 34
2010-08-20 10:01:48,413 DEBUG [http-8080-1] o.g.m.a.i.AMF3Deserializer
[AMF3Deserializer.java : 491] getFromStoredStrings(index=17)
2010-08-20 10:01:48,413 DEBUG [http-8080-1] o.g.m.a.i.AMF3Deserializer
[AMF3Deserializer.java : 493] getFromStoredStrings() ->
"ACED0005757200135B4C6A6176612E6C616E672E4F626A6563743B90CE589F1073296C02000078700000000270737200106A6176612E7574696C2E4269745365746EFD887E3934AB210300015B0004626974737400025B4A7870757200025B4A782004B512B17593020000787000000001000000000000000778"
2010-08-20 10:01:48,413 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 224]
readAMF3String() ->
"ACED0005757200135B4C6A6176612E6C616E672E4F626A6563743B90CE589F1073296C02000078700000000270737200106A6176612E7574696C2E4269745365746EFD887E3934AB210300015B0004626974737400025B4A7870757200025B4A782004B512B17593020000787000000001000000000000000778"
2010-08-20 10:01:48,413 DEBUG [http-8080-1] o.g.m.a.i.AMF3Deserializer
[AMF3Deserializer.java : 499]
addToStoredObjects(o=org.mycompany.myartifactid.entity.jpa.Note@c63304)
at index=8
2010-08-20 10:01:48,413 DEBUG [http-8080-1] o.g.m.a.i.AMF3Deserializer
[AMF3Deserializer.java : 367] readAMF3Object() - using
externalizer=org.granite.openjpa.OpenJpaExternalizer@10bcd15
2010-08-20 10:01:48,413 DEBUG [http-8080-1] o.g.o.OpenJpaExternalizer
[OpenJpaExternalizer.java : 126] Reading entity
"org.mycompany.myartifactid.entity.jpa.Note" with fields [id,
noteText, noteTs, noteType]
2010-08-20 10:01:48,413 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 84]
readObject()...
2010-08-20 10:01:48,413 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 157]
readAMF3Integer() -> 4
2010-08-20 10:01:48,413 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 103]
readObject(type=0x04)
2010-08-20 10:01:48,413 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 157]
readAMF3Integer() -> 1027
2010-08-20 10:01:48,413 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 84]
readObject()...
2010-08-20 10:01:48,413 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 157]
readAMF3Integer() -> 6
2010-08-20 10:01:48,413 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 103]
readObject(type=0x06)
2010-08-20 10:01:48,413 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 174]
readAMF3String()...
2010-08-20 10:01:48,429 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 157]
readAMF3Integer() -> 97
2010-08-20 10:01:48,429 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 181]
readAMF3String() - length=48
2010-08-20 10:01:48,429 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 217]
readAMF3String() - result="Test note 2 added"
2010-08-20 10:01:48,429 DEBUG [http-8080-1] o.g.m.a.i.AMF3Deserializer
[AMF3Deserializer.java : 486] addToStoredStrings(s="Test note 2
added") at index=20
2010-08-20 10:01:48,429 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 224]
readAMF3String() -> "Test note 2 added"
2010-08-20 10:01:48,429 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 84]
readObject()...
2010-08-20 10:01:48,429 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 157]
readAMF3Integer() -> 8
2010-08-20 10:01:48,429 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 103]
readObject(type=0x08)
2010-08-20 10:01:48,429 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 157]
readAMF3Integer() -> 1
2010-08-20 10:01:48,429 DEBUG [http-8080-1] o.g.m.a.i.AMF3Deserializer
[AMF3Deserializer.java : 499] addToStoredObjects(o=Fri Jul 30 11:19:40
EDT 2010) at index=9
2010-08-20 10:01:48,429 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 241]
readAMF3Date() -> Fri Jul 30 11:19:40 EDT 2010
2010-08-20 10:01:48,429 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 84]
readObject()...
2010-08-20 10:01:48,429 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 157]
readAMF3Integer() -> 10
2010-08-20 10:01:48,429 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 103]
readObject(type=0x0A)
2010-08-20 10:01:48,429 DEBUG [http-8080-1] o.g.m.a.i.AMF3Deserializer
[AMF3Deserializer.java : 286] readAMF3Object()...
2010-08-20 10:01:48,429 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 157]
readAMF3Integer() -> 17
2010-08-20 10:01:48,429 DEBUG [http-8080-1] o.g.m.a.i.AMF3Deserializer
[AMF3Deserializer.java : 291] readAMF3Object() - type=0x11
2010-08-20 10:01:48,429 DEBUG [http-8080-1] o.g.m.a.i.AMF3Deserializer
[AMF3Deserializer.java : 297] readAMF3Object() - inlineClassDef=false
2010-08-20 10:01:48,429 DEBUG [http-8080-1] o.g.m.a.i.AMF3Deserializer
[AMF3Deserializer.java : 522] getFromStoredClassDescriptors(index=4)
2010-08-20 10:01:48,429 DEBUG [http-8080-1] o.g.m.a.i.AMF3Deserializer
[AMF3Deserializer.java : 524] getFromStoredClassDescriptors() ->
org.granite.messaging.amf.io.util.DefaultActionScriptClassDescriptor {
  type=org.mycompany.myartifactid.entity.jpa.NoteType,
  instantiator=null,
  encoding=1,
  externalizer=org.granite.openjpa.OpenJpaExternalizer@10bcd15,
  converters=org.granite.messaging.amf.io.convert.Converters@1dbc53d,
  properties=[]
}

2010-08-20 10:01:48,429 DEBUG [http-8080-1] o.g.m.a.i.AMF3Deserializer
[AMF3Deserializer.java : 340] readAMF3Object() -
actionScriptClassDescriptor=org.granite.messaging.amf.io.util.DefaultActionScriptClassDescriptor
{
  type=org.mycompany.myartifactid.entity.jpa.NoteType,
  instantiator=null,
  encoding=1,
  externalizer=org.granite.openjpa.OpenJpaExternalizer@10bcd15,
  converters=org.granite.messaging.amf.io.convert.Converters@1dbc53d,
  properties=[]
}

2010-08-20 10:01:48,429 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 84]
readObject()...
2010-08-20 10:01:48,429 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 157]
readAMF3Integer() -> 2
2010-08-20 10:01:48,429 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 103]
readObject(type=0x02)
2010-08-20 10:01:48,429 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 84]
readObject()...
2010-08-20 10:01:48,429 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 157]
readAMF3Integer() -> 1
2010-08-20 10:01:48,429 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 103]
readObject(type=0x01)
2010-08-20 10:01:48,429 DEBUG [http-8080-1] o.g.m.a.i.AMF3Deserializer
[AMF3Deserializer.java : 499]
addToStoredObjects(o=org.mycompany.myartifactid.entity.jpa.NoteType@3f8a94)
at index=10
2010-08-20 10:01:48,429 DEBUG [http-8080-1] o.g.m.a.i.AMF3Deserializer
[AMF3Deserializer.java : 367] readAMF3Object() - using
externalizer=org.granite.openjpa.OpenJpaExternalizer@10bcd15
2010-08-20 10:01:48,429 DEBUG [http-8080-1] o.g.o.OpenJpaExternalizer
[OpenJpaExternalizer.java : 126] Reading entity
"org.mycompany.myartifactid.entity.jpa.NoteType" with fields
[description, id, name]
2010-08-20 10:01:48,429 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 84]
readObject()...
2010-08-20 10:01:48,429 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 157]
readAMF3Integer() -> 5
2010-08-20 10:01:48,429 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 103]
readObject(type=0x05)
2010-08-20 10:01:48,429 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 166]
readAMF3Double() -> null
2010-08-20 10:01:48,429 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 84]
readObject()...
2010-08-20 10:01:48,429 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 157]
readAMF3Integer() -> 6
2010-08-20 10:01:48,429 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 103]
readObject(type=0x06)
2010-08-20 10:01:48,429 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 174]
readAMF3String()...
2010-08-20 10:01:48,429 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 157]
readAMF3Integer() -> 73
2010-08-20 10:01:48,429 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 181]
readAMF3String() - length=36
2010-08-20 10:01:48,429 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 217]
readAMF3String() - result="EA1A6A19-5627-9570-349E-8FCE2E3F82D3"
2010-08-20 10:01:48,429 DEBUG [http-8080-1] o.g.m.a.i.AMF3Deserializer
[AMF3Deserializer.java : 486]
addToStoredStrings(s="EA1A6A19-5627-9570-349E-8FCE2E3F82D3") at
index=21
2010-08-20 10:01:48,429 DEBUG [http-8080-1]
o.g.m.a.i.AMF3Deserializer_MORE [AMF3Deserializer.java : 224]
readAMF3String() -> "EA1A6A19-5627-9570-349E-8FCE2E3F82D3"
2010-08-20 10:01:48,429 ERROR [http-8080-1] o.g.m.w.AMFMessageFilter
[AMFMessageFilter.java : 142] AMF message error
org.granite.messaging.amf.io.AMF3SerializationException
        at
org.granite.messaging.amf.io.AMF3Deserializer.readObject(AMF3Deserializer.java:
94)
        at
org.granite.openjpa.OpenJpaExternalizer.readExternal(OpenJpaExternalizer.java:
128)
        at
org.granite.messaging.amf.io.AMF3Deserializer.readAMF3Object(AMF3Deserializer.java:
369)
        at
org.granite.messaging.amf.io.AMF3Deserializer.readObject(AMF3Deserializer.java:
126)
        at
org.granite.messaging.amf.io.AMF3Deserializer.readObject(AMF3Deserializer.java:
88)
        at
org.granite.openjpa.OpenJpaExternalizer.readExternal(OpenJpaExternalizer.java:
128)
        at
org.granite.messaging.amf.io.AMF3Deserializer.readAMF3Object(AMF3Deserializer.java:
369)
        at
org.granite.messaging.amf.io.AMF3Deserializer.readObject(AMF3Deserializer.java:
126)
        at
org.granite.messaging.amf.io.AMF3Deserializer.readObject(AMF3Deserializer.java:
88)
        at
org.granite.openjpa.OpenJpaExternalizer.readExternal(OpenJpaExternalizer.java:
128)
        at
org.granite.messaging.amf.io.AMF3Deserializer.readAMF3Object(AMF3Deserializer.java:
369)
        at
org.granite.messaging.amf.io.AMF3Deserializer.readObject(AMF3Deserializer.java:
126)
        at
org.granite.messaging.amf.io.AMF3Deserializer.readObject(AMF3Deserializer.java:
88)
        at
org.granite.messaging.amf.io.AMF3Deserializer.readAMF3Array(AMF3Deserializer.java:
261)
        at
org.granite.messaging.amf.io.AMF3Deserializer.readObject(AMF3Deserializer.java:
124)
        at
org.granite.messaging.amf.io.AMF3Deserializer.readObject(AMF3Deserializer.java:
88)
        at
org.granite.messaging.persistence.AbstractExternalizablePersistentCollection.readExternal(AbstractExternalizablePersistentCollection.java:
97)
        at
org.granite.messaging.amf.io.AMF3Deserializer.readAMF3Object(AMF3Deserializer.java:
389)
        at
org.granite.messaging.amf.io.AMF3Deserializer.readObject(AMF3Deserializer.java:
126)
        at
org.granite.messaging.amf.io.AMF3Deserializer.readObject(AMF3Deserializer.java:
88)
        at
org.granite.openjpa.OpenJpaExternalizer.readExternal(OpenJpaExternalizer.java:
128)
        at
org.granite.messaging.amf.io.AMF3Deserializer.readAMF3Object(AMF3Deserializer.java:
369)
        at
org.granite.messaging.amf.io.AMF3Deserializer.readObject(AMF3Deserializer.java:
126)
        at
org.granite.messaging.amf.io.AMF3Deserializer.readObject(AMF3Deserializer.java:
88)
        at
org.granite.messaging.amf.io.AMF3Deserializer.readAMF3Array(AMF3Deserializer.java:
261)
        at
org.granite.messaging.amf.io.AMF3Deserializer.readObject(AMF3Deserializer.java:
124)
        at
org.granite.messaging.amf.io.AMF3Deserializer.readAMF3Object(AMF3Deserializer.java:
403)
        at
org.granite.messaging.amf.io.AMF3Deserializer.readObject(AMF3Deserializer.java:
126)
        at
org.granite.messaging.amf.io.AMF3Deserializer.readObject(AMF3Deserializer.java:
88)
        at
org.granite.messaging.amf.io.AMF0Deserializer.readAMF3Data(AMF0Deserializer.java:
310)
        at
org.granite.messaging.amf.io.AMF0Deserializer.readData(AMF0Deserializer.java:
362)
        at
org.granite.messaging.amf.io.AMF0Deserializer.readArray(AMF0Deserializer.java:
225)
        at
org.granite.messaging.amf.io.AMF0Deserializer.readData(AMF0Deserializer.java:
348)
        at
org.granite.messaging.amf.io.AMF0Deserializer.readBodies(AMF0Deserializer.java:
141)
        at
org.granite.messaging.amf.io.AMF0Deserializer.<init>(AMF0Deserializer.java:
79)
        at
org.granite.messaging.webapp.AMFMessageFilter.doFilter(AMFMessageFilter.java:
110)
        at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:
235)
        at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:
206)
        at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:
233)
        at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:
191)
        at
org.apache.openejb.tomcat.catalina.OpenEJBValve.invoke(OpenEJBValve.java:
45)
        at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:
127)
        at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:
102)
        at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:
109)
        at
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:
298)
        at
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:
852)
        at org.apache.coyote.http11.Http11Protocol
$Http11ConnectionHandler.process(Http11Protocol.java:588)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:
489)
        at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.RuntimeException: Could not read externalized
object: org.mycompany.myartifactid.entity.jpa.NoteType@3f8a94
        at
org.granite.messaging.amf.io.AMF3Deserializer.readAMF3Object(AMF3Deserializer.java:
373)
        at
org.granite.messaging.amf.io.AMF3Deserializer.readObject(AMF3Deserializer.java:
126)
        at
org.granite.messaging.amf.io.AMF3Deserializer.readObject(AMF3Deserializer.java:
88)
        ... 48 common frames omitted
Caused by:
org.granite.messaging.amf.io.convert.NoConverterFoundException: Cannot
convert: EA1A6A19-5627-9570-349E-8FCE2E3F82D3 to: class java.lang.Long
        at
org.granite.messaging.amf.io.convert.Converters.getConverter(Converters.java:
119)
        at
org.granite.messaging.amf.io.convert.Converters.convert(Converters.java:
132)
        at
org.granite.openjpa.OpenJpaExternalizer.readExternal(OpenJpaExternalizer.java:
149)
        at
org.granite.messaging.amf.io.AMF3Deserializer.readAMF3Object(AMF3Deserializer.java:
369)
        ... 50 common frames omitted

~~~~~~~
Environment
~~~~~~~

Here is my environment:
gas v2.1
graniteDs v2.1.0.GA
Flex 3.5
tomcat v6
open-ejb v3.1.2

~~~~~~~
~~~~~~~

@Entity
public class ReviewPlan implements Serializable {
        private static final long serialVersionUID = 1L;

        @Id
        private Long id;

        @ManyToMany(cascade = CascadeType.ALL)
        @JoinTable(name = "REVIEW_PLAN_NOTES", joinColumns = @JoinColumn(name
= "REVIEW_PLAN_ID"), inverseJoinColumns = @JoinColumn(name =
"NOTE_ID"))
        private Set<Note> noteCollection;

        public ReviewPlan() {
                super();
        }

        public Long getId() {
                return id;
        }

        public Set<Note> getNoteCollection() {
                return noteCollection;
        }

        public void setId(final Long id) {
                this.id = id;
        }

        public void setNoteCollection(final Set<Note> noteCollection) {
                this.noteCollection = noteCollection;
        }

}

@Entity
public class Note implements Serializable {
        private static final long serialVersionUID = 1L;

        @Id
        private Long id;

        @Column(name = "NOTE_TEXT")
        private String noteText;

        @Column(name = "NOTE_TS")
        private Date noteTs;

        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "NOTE_TYPE_ID")
        private NoteType noteType;

        public Note() {
                super();
        }

        public Long getId() {
                return id;
        }

        public String getNoteText() {
                return noteText;
        }

        public Date getNoteTs() {
                return noteTs;
        }

        public NoteType getNoteType() {
                return noteType;
        }

        public void setId(final Long id) {
                this.id = id;
        }

        public void setNoteText(final String noteText) {
                this.noteText = noteText;
        }

        public void setNoteTs(final Date noteTs) {
                this.noteTs = noteTs;
        }

        public void setNoteType(final NoteType noteType) {
                this.noteType = noteType;
        }

}

@Entity
public class NoteType implements Serializable {
        private static final long serialVersionUID = 1L;

        @Id
        private Long id;

        private String name;

        private String description;

        public Long getId() {
                return id;
        }

        public void setId(final Long id) {
                this.id = id;
        }

        public String getName() {
                return name;
        }

        public void setName(final String name) {
                this.name = name;
        }

        public String getDescription() {
                return description;
        }

        public void setDescription(final String description) {
                this.description = description;
        }

}

/**
 * Generated by Gas3 v2.1.0 (Granite Data Services).
 *
 * WARNING: DO NOT CHANGE THIS FILE. IT MAY BE OVERWRITTEN EACH TIME
YOU USE
 * THE GENERATOR. INSTEAD, EDIT THE INHERITED CLASS (ReviewPlan.as).
 */

package entity.jpa {

    import flash.utils.IDataInput;
    import flash.utils.IDataOutput;
    import flash.utils.IExternalizable;
    import mx.collections.ListCollectionView;
    import org.granite.collections.IPersistentCollection;
    import org.granite.meta;

    use namespace meta;

    [Bindable]
    public class ReviewPlanBase implements IExternalizable {

        private var __initialized:Boolean = true;
        private var __detachedState:String = null;

        private var _id:Number;
        private var _noteCollection:ListCollectionView;

        meta function isInitialized(name:String = null):Boolean {
            if (!name)
                return __initialized;

            var property:* = this[name];
            return (
                (!(property is ReviewPlan) || (property as
ReviewPlan).meta::isInitialized()) &&
                (!(property is IPersistentCollection) || (property as
IPersistentCollection).isInitialized())
            );
        }

        public function set id(value:Number):void {
            _id = value;
        }
        public function get id():Number {
            return _id;
        }

        public function set
noteCollection(value:ListCollectionView):void {
            _noteCollection = value;
        }
        public function get noteCollection():ListCollectionView {
            return _noteCollection;
        }

        public function readExternal(input:IDataInput):void {
            __initialized = input.readObject() as Boolean;
            __detachedState = input.readObject() as String;
            if (meta::isInitialized()) {
                _id = function(o:*):Number { return (o is Number ? o
as Number : Number.NaN) } (input.readObject());
                _noteCollection = input.readObject() as
ListCollectionView;
            }
            else {
                _id = function(o:*):Number { return (o is Number ? o
as Number : Number.NaN) } (input.readObject());
            }
        }

        public function writeExternal(output:IDataOutput):void {
            output.writeObject(__initialized);
            output.writeObject(__detachedState);
            if (meta::isInitialized()) {
                output.writeObject(_id);
                output.writeObject(_noteCollection);
            }
            else {
                output.writeObject(_id);
            }
        }
    }

}

/**
 * Generated by Gas3 v2.1.0 (Granite Data Services).
 *
 * WARNING: DO NOT CHANGE THIS FILE. IT MAY BE OVERWRITTEN EACH TIME
YOU USE
 * THE GENERATOR. INSTEAD, EDIT THE INHERITED CLASS (Note.as).
 */

package entity.jpa {

    import flash.utils.IDataInput;
    import flash.utils.IDataOutput;
    import flash.utils.IExternalizable;
    import org.granite.collections.IPersistentCollection;
    import org.granite.meta;

    use namespace meta;

    [Bindable]
    public class NoteBase implements IExternalizable {

        private var __initialized:Boolean = true;
        private var __detachedState:String = null;

        private var _id:Number;
        private var _noteText:String;
        private var _noteTs:Date;
        private var _noteType:NoteType;

        meta function isInitialized(name:String = null):Boolean {
            if (!name)
                return __initialized;

            var property:* = this[name];
            return (
                (!(property is Note) || (property as
Note).meta::isInitialized()) &&
                (!(property is IPersistentCollection) || (property as
IPersistentCollection).isInitialized())
            );
        }

        public function set id(value:Number):void {
            _id = value;
        }
        public function get id():Number {
            return _id;
        }

        public function set noteText(value:String):void {
            _noteText = value;
        }
        public function get noteText():String {
            return _noteText;
        }

        public function set noteTs(value:Date):void {
            _noteTs = value;
        }
        public function get noteTs():Date {
            return _noteTs;
        }

        public function set noteType(value:NoteType):void {
            _noteType = value;
        }
        public function get noteType():NoteType {
            return _noteType;
        }

        public function readExternal(input:IDataInput):void {
            __initialized = input.readObject() as Boolean;
            __detachedState = input.readObject() as String;
            if (meta::isInitialized()) {
                _id = function(o:*):Number { return (o is Number ? o
as Number : Number.NaN) } (input.readObject());
                _noteText = input.readObject() as String;
                _noteTs = input.readObject() as Date;
                _noteType = input.readObject() as NoteType;
            }
            else {
                _id = function(o:*):Number { return (o is Number ? o
as Number : Number.NaN) } (input.readObject());
            }
        }

        public function writeExternal(output:IDataOutput):void {
            output.writeObject(__initialized);
            output.writeObject(__detachedState);
            if (meta::isInitialized()) {
                output.writeObject(_id);
                output.writeObject(_noteText);
                output.writeObject(_noteTs);
                output.writeObject(_noteType);
            }
            else {
                output.writeObject(_id);
            }
        }
    }

}

/**
 * Generated by Gas3 v2.1.0 (Granite Data Services).
 *
 * WARNING: DO NOT CHANGE THIS FILE. IT MAY BE OVERWRITTEN EACH TIME
YOU USE
 * THE GENERATOR. INSTEAD, EDIT THE INHERITED CLASS (NoteType.as).
 */

package entity.jpa {

    import flash.utils.IDataInput;
    import flash.utils.IDataOutput;
    import flash.utils.IExternalizable;
    import org.granite.collections.IPersistentCollection;
    import org.granite.meta;

    use namespace meta;

    [Bindable]
    public class NoteTypeBase implements IExternalizable {

        private var __initialized:Boolean = true;
        private var __detachedState:String = null;

        private var _description:String;
        private var _id:Number;
        private var _name:String;

        meta function isInitialized(name:String = null):Boolean {
            if (!name)
                return __initialized;

            var property:* = this[name];
            return (
                (!(property is NoteType) || (property as
NoteType).meta::isInitialized()) &&
                (!(property is IPersistentCollection) || (property as
IPersistentCollection).isInitialized())
            );
        }

        public function set description(value:String):void {
            _description = value;
        }
        public function get description():String {
            return _description;
        }

        public function set id(value:Number):void {
            _id = value;
        }
        public function get id():Number {
            return _id;
        }

        public function set name(value:String):void {
            _name = value;
        }
        public function get name():String {
            return _name;
        }

        public function readExternal(input:IDataInput):void {
            __initialized = input.readObject() as Boolean;
            __detachedState = input.readObject() as String;
            if (meta::isInitialized()) {
                _description = input.readObject() as String;
                _id = function(o:*):Number { return (o is Number ? o
as Number : Number.NaN) } (input.readObject());
                _name = input.readObject() as String;
            }
            else {
                _id = function(o:*):Number { return (o is Number ? o
as Number : Number.NaN) } (input.readObject());
            }
        }

        public function writeExternal(output:IDataOutput):void {
            output.writeObject(__initialized);
            output.writeObject(__detachedState);
            if (meta::isInitialized()) {
                output.writeObject(_description);
                output.writeObject(_id);
                output.writeObject(_name);
            }
            else {
                output.writeObject(_id);
            }
        }
    }

}

~~~~~
grainite-config.xml
~~~~~
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE granite-config PUBLIC "-//Granite Data Services//DTD granite-
config internal//EN"
    "http://www.graniteds.org/public/dtd/2.0.0/granite-config.dtd">

<granite-config>
        <class-getter type="org.granite.openjpa.OpenJpaClassGetter"/>
        <externalizers>
                <externalizer type="org.granite.openjpa.OpenJpaExternalizer">
                        <include annotated-with="javax.persistence.Entity" />
                        <include annotated-with="javax.persistence.MappedSuperclass" />
                        <include annotated-with="javax.persistence.Embeddable" />
                </externalizer>
                <externalizer
type="org.granite.messaging.amf.io.util.externalizer.EnumExternalizer">
                        <include instance-of="java.lang.Enum" />
                </externalizer>
        </externalizers>
</granite-config>

Franck Wolff added a comment - 25/Aug/10 11:49 AM
I have commited a patch but I can't test it for now (I don't have any project/environment with openjpa).

Could you get the last build here: http://www.graniteds.org/bamboo/browse/GDS-CORE-633/artifact/graniteds.zip/graniteds-2.2.0.RC1.zip and tell me if it fixes your problem?

Thanks, Franck.

Franck Wolff added a comment - 25/Aug/10 11:56 AM
BTW: it is normal to get two NoteType instances on Flex side. But they should have their __initialized variables set to false and everything else set to null. The openjpa externalizer didn't test this initialized flag at deserialization time and that was (most probably) the problem.

Louis S added a comment - 25/Aug/10 09:28 PM
I tested using your update, but unfortunately I'm seeing the same error.

I see where you added the check to see if the value is an instance of PersistenceCapable but after stepping through the code, I see it is never making it there.

This is because the detachedState value when processing the NoteType object is null and therefore the a new instance of DefaultExternalizer is returned.

{code}
        // Read detached state...
        String detachedState = (String)in.readObject();
        
        // New entity.
        if (detachedState == null)
         return super.newInstance(type, in);
{code}

*Also the boolean initialized value is false for the NoteType

Louis S added a comment - 25/Aug/10 09:31 PM
I think making changing the order as follows resolves the issue:

// Pseudo-proxy (uninitialized entity).
if (!initialized) {
final Object id = in.readObject();
if (id != null && (!clazz.isAnnotationPresent(IdClass.class) || !clazz.getAnnotation(IdClass.class).value().equals(id.getClass()))) {
throw new RuntimeException("Id for OpenJPA pseudo-proxy should be null or IdClass (" + type + ")");
}
return null;
}

// New entity.
if (detachedState == null) {
return super.newInstance(type, in);
}

Franck Wolff added a comment - 26/Aug/10 11:11 AM
You're right, thanks for the patch. It's commited in the trunk.
Tell us if it's ok,
Franck.

Louis S added a comment - 26/Aug/10 03:05 PM
I just tested. You can close the ticket.

Franck Wolff added a comment - 26/Aug/10 03:12 PM
Done. Thanks!