You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@openjpa.apache.org by Jere McDevitt <je...@alltel.net> on 2007/06/28 04:25:47 UTC

Serialization between ehanced and non-enhanced objects

The documentation makes the following claim:

 


2.4.  Serializing Enhanced Types 


By default, OpenJPA maintains serialization compatibility between the
enhanced and unenhanced versions of a class. This allows you to serialize
instances between a server using OpenJPA and a client that does not have
access to enhanced classes or OpenJPA libraries. In some cases, however, you
can make the persist and attach processes more robust and efficient by
allowing breaks in serialization compatibility. See Section
<http://openjpa.apache.org/docs/openjpa-0.9.0-incubating/manual/manual.html#
ref_guide_detach_graph>  1.3, " Defining the Detached Object Graph " for
details. 

 

However, in actual practice I have not been able to make this work.  When I
have a class structure like:

 

@Entity

public class User {

            

            @Id

            private String userId;

 

            @Column(nullable=false)

            private String password;

 

            @ManyToMany

            @JoinTable(name="UserRoles",

                        joinColumn=@JoinColumn(name="userId",
refererencedColumName="userId"),

                        inverseJoinColumns=@JoinColumn(name="rolename",
referencedColumnName="roleName"))

            List<Role>  roles;

 

}

 

@Entity

public class Role {

 

            @Id 

            private String roleName;

 

}

 

and I enhance these classes, the enhancer adds into the User.class file an
additional object of type org.apache.openjpa.util.java$util$ArrayList$proxy

which actually wrapps the 'roles' field.  Additionally, all of the actual
field attributes are encapsulated inside another object called 'default'.  I
can't seem to serialize in any manner that will work,  either with
ObjectOutputStream, java.beans.XMLEncoder or XStream.toXML,

 

When an attempt is made to deserialize in another JVM that does not have the
enhanced classes, and does not have the openjpa package at all, it fails.
Straight ObjectOutputStream fails with class not found for the above
ArrayList$proxy, XMLCoder generates NullPointerExceptions because it can't
find the class, and XMLStream doesn't recognized either the class or the
'default' tag that was generated on the server side.

 

I tried adding in the 

 

@DetachedState private Object state 

 

but that doesn't seem to do anything but add an additional field that gets
filled with a byte array.

 

 

The XML that is provided by java.beans.XMLEncode which shows the location of
the proxy object is:

 

<?xml version="1.0" encoding="UTF-8"?> 
<java version="1.6.0" class="java.beans.XMLDecoder"> 
 <object class="commons.UserProfile"> 
  <void property="emailAddress"> 
   <string></string> 
  </void> 
  <void property="firstName"> 
   <string>System</string> 
  </void> 
  <void property="lastName"> 
   <string>Administrator</string> 
  </void> 
  <void property="password"> 
   <string>d69ea425c1a1ad4043f915887f9cd562</string> 
  </void> 
  <void property="phoneNumber"> 
   <string></string> 
  </void> 
  <void property="roles"> 
   <object class="org.apache.openjpa.util.java$util$ArrayList$proxy"> 
    <void method="add"> 
     <object id="Role0" class="commons.Role"> 
      <void property="roleName"> 
       <string>player</string> 
      </void> 
     </object> 
    </void> 
    <void method="add"> 
     <object id="Role1" class="commons.Role"> 
      <void property="roleName"> 
       <string>dungeonmaster</string> 
      </void> 
     </object> 
    </void> 
    <void method="add"> 
     <object idref="Role0"/> 
    </void> 
    <void method="add"> 
     <object idref="Role1"/> 
    </void> 
   </object> 
  </void> 
  <void property="userId"> 
   <string>admin</string> 
  </void> 
 </object> 
</java> 
 

So how do you actually implement serialization from an enhanced server side
object to a non-enhanced client side object?

 


RE: Serialization between ehanced and non-enhanced objects

Posted by Pinaki Poddar <pp...@bea.com>.
Jere,
  The mailserver perhaps blocks attachement. 
  Can you please post them as attachement to a JIRA issue
http://issues.apache.org/jira/browse/OPENJPA?

One setting that impacts serialization behavior is openjpa.DetachState
(http://openjpa.apache.org/docs/latest/manual/manual.html#ref_guide_deta
ch_graph). 

But these settings are not the cause of what you are observing on
serialization of proxy sco (ArrayList) classes.
your enhanced classes will reveal further. 

  


Pinaki Poddar
972.834.2865

-----Original Message-----
From: Jere McDevitt [mailto:jeremcd349@alltel.net] 
Sent: Thursday, June 28, 2007 7:46 PM
To: dev@openjpa.apache.org
Cc: plinskey@gmail.com
Subject: RE: Serialization between ehanced and non-enhanced objects

OpenJPA version is 1.0.0-SNAPSHOT
Persistence.xml file has:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
version="1.0">
  <persistence-unit name="ddhelper" transaction-type="RESOURCE_LOCAL">
    <description>This the persistence details for the ddhelper
application</description>
 
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provid
er>
    <class>com.farthink.ddhelper.commons.UserProfile</class>
    <class>com.farthink.ddhelper.commons.Role</class>
    <properties>
      <property name="openjpa.ConnectionDriverName" value="@DRIVER@" />
      <property name="openjpa.ConnectionURL" value="@URL@" />
      <property name="openjpa.ConnectionUserName" value="@USER@" />
      <property name="openjpa.ConnectionPassword" value="@PASSWORD@" />
      <property name="openjpa.Log" value="DefaultLevel=Warn,
Runtime=Info"
/>
      <property name="openjpa.MetaDataFactory" value="jpa" />
      <property name="openjpa.jdbc.SynchronizeMappings"
value="buildSchema(ForeignKeys=true)" />
    </properties>
  </persistence-unit>
</persistence>

I invoke the enhancer from an ANT task with:

<taskdef name="openjpac"
classname="org.apache.openjpa.ant.PCEnhancerTask">
      <classpath refid="compile.classpath"/> </taskdef>

And the two enhanced classes (UserProfile and Role) are attached, as are
the original source files.

Let me know if there is something else you need.

Thanks

Jere


-----Original Message-----
From: Patrick Linskey [mailto:plinskey@gmail.com]
Sent: Thursday, June 28, 2007 3:37 AM
To: dev@openjpa.apache.org; jeremcd349@alltel.net
Subject: Re: Serialization between ehanced and non-enhanced objects

Hi,

It sounds like our proxy list wrappers are not exernalizing themselves
properly in your environment. What version of OpenJPA are you using?
Also, can you post your class file itself so that we can take a closer
look at it? Also, can you post your OpenJPA configuration settings?

-Patrick

On 6/27/07, Jere McDevitt <je...@alltel.net> wrote:
> The documentation makes the following claim:
>
>
>
>
> 2.4.  Serializing Enhanced Types
>
>
> By default, OpenJPA maintains serialization compatibility between the 
> enhanced and unenhanced versions of a class. This allows you to 
> serialize instances between a server using OpenJPA and a client that 
> does not have access to enhanced classes or OpenJPA libraries. In some

> cases, however,
you
> can make the persist and attach processes more robust and efficient by

> allowing breaks in serialization compatibility. See Section
>
<http://openjpa.apache.org/docs/openjpa-0.9.0-incubating/manual/manual.h
tml#
> ref_guide_detach_graph>  1.3, " Defining the Detached Object Graph " 
> for details.
>
>
>
> However, in actual practice I have not been able to make this work.  
> When
I
> have a class structure like:
>
>
>
> @Entity
>
> public class User {
>
>
>
>             @Id
>
>             private String userId;
>
>
>
>             @Column(nullable=false)
>
>             private String password;
>
>
>
>             @ManyToMany
>
>             @JoinTable(name="UserRoles",
>
>                         joinColumn=@JoinColumn(name="userId",
> refererencedColumName="userId"),
>
>                         
> inverseJoinColumns=@JoinColumn(name="rolename",
> referencedColumnName="roleName"))
>
>             List<Role>  roles;
>
>
>
> }
>
>
>
> @Entity
>
> public class Role {
>
>
>
>             @Id
>
>             private String roleName;
>
>
>
> }
>
>
>
> and I enhance these classes, the enhancer adds into the User.class 
> file an additional object of type
org.apache.openjpa.util.java$util$ArrayList$proxy
>
> which actually wrapps the 'roles' field.  Additionally, all of the 
> actual field attributes are encapsulated inside another object called
'default'.
I
> can't seem to serialize in any manner that will work,  either with 
> ObjectOutputStream, java.beans.XMLEncoder or XStream.toXML,
>
>
>
> When an attempt is made to deserialize in another JVM that does not 
> have
the
> enhanced classes, and does not have the openjpa package at all, it
fails.
> Straight ObjectOutputStream fails with class not found for the above 
> ArrayList$proxy, XMLCoder generates NullPointerExceptions because it 
> can't find the class, and XMLStream doesn't recognized either the 
> class or the 'default' tag that was generated on the server side.
>
>
>
> I tried adding in the
>
>
>
> @DetachedState private Object state
>
>
>
> but that doesn't seem to do anything but add an additional field that 
> gets filled with a byte array.
>
>
>
>
>
> The XML that is provided by java.beans.XMLEncode which shows the 
> location
of
> the proxy object is:
>
>
>
> <?xml version="1.0" encoding="UTF-8"?> <java version="1.6.0" 
> class="java.beans.XMLDecoder">  <object class="commons.UserProfile">
>   <void property="emailAddress">
>    <string></string>
>   </void>
>   <void property="firstName">
>    <string>System</string>
>   </void>
>   <void property="lastName">
>    <string>Administrator</string>
>   </void>
>   <void property="password">
>    <string>d69ea425c1a1ad4043f915887f9cd562</string>
>   </void>
>   <void property="phoneNumber">
>    <string></string>
>   </void>
>   <void property="roles">
>    <object class="org.apache.openjpa.util.java$util$ArrayList$proxy">
>     <void method="add">
>      <object id="Role0" class="commons.Role">
>       <void property="roleName">
>        <string>player</string>
>       </void>
>      </object>
>     </void>
>     <void method="add">
>      <object id="Role1" class="commons.Role">
>       <void property="roleName">
>        <string>dungeonmaster</string>
>       </void>
>      </object>
>     </void>
>     <void method="add">
>      <object idref="Role0"/>
>     </void>
>     <void method="add">
>      <object idref="Role1"/>
>     </void>
>    </object>
>   </void>
>   <void property="userId">
>    <string>admin</string>
>   </void>
>  </object>
> </java>
>
>
> So how do you actually implement serialization from an enhanced server
side
> object to a non-enhanced client side object?
>
>
>
>


--
Patrick Linskey
202 669 5907

Notice:  This email message, together with any attachments, may contain information  of  BEA Systems,  Inc.,  its subsidiaries  and  affiliated entities,  that may be confidential,  proprietary,  copyrighted  and/or legally privileged, and is intended solely for the use of the individual or entity named in this message. If you are not the intended recipient, and have received this message in error, please immediately return this by email and then delete it.

RE: Serialization between ehanced and non-enhanced objects

Posted by Jere McDevitt <je...@alltel.net>.
OpenJPA version is 1.0.0-SNAPSHOT
Persistence.xml file has:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
  <persistence-unit name="ddhelper" transaction-type="RESOURCE_LOCAL">
    <description>This the persistence details for the ddhelper
application</description>
 
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
    <class>com.farthink.ddhelper.commons.UserProfile</class>
    <class>com.farthink.ddhelper.commons.Role</class>
    <properties>
      <property name="openjpa.ConnectionDriverName" value="@DRIVER@" />
      <property name="openjpa.ConnectionURL" value="@URL@" />
      <property name="openjpa.ConnectionUserName" value="@USER@" />
      <property name="openjpa.ConnectionPassword" value="@PASSWORD@" />
      <property name="openjpa.Log" value="DefaultLevel=Warn, Runtime=Info"
/>
      <property name="openjpa.MetaDataFactory" value="jpa" />
      <property name="openjpa.jdbc.SynchronizeMappings"
value="buildSchema(ForeignKeys=true)" />
    </properties>
  </persistence-unit>
</persistence>

I invoke the enhancer from an ANT task with:

<taskdef name="openjpac" classname="org.apache.openjpa.ant.PCEnhancerTask">
      <classpath refid="compile.classpath"/>
</taskdef>

And the two enhanced classes (UserProfile and Role) are attached, as are the
original source files.

Let me know if there is something else you need.

Thanks

Jere


-----Original Message-----
From: Patrick Linskey [mailto:plinskey@gmail.com] 
Sent: Thursday, June 28, 2007 3:37 AM
To: dev@openjpa.apache.org; jeremcd349@alltel.net
Subject: Re: Serialization between ehanced and non-enhanced objects

Hi,

It sounds like our proxy list wrappers are not exernalizing themselves
properly in your environment. What version of OpenJPA are you using?
Also, can you post your class file itself so that we can take a closer
look at it? Also, can you post your OpenJPA configuration settings?

-Patrick

On 6/27/07, Jere McDevitt <je...@alltel.net> wrote:
> The documentation makes the following claim:
>
>
>
>
> 2.4.  Serializing Enhanced Types
>
>
> By default, OpenJPA maintains serialization compatibility between the
> enhanced and unenhanced versions of a class. This allows you to serialize
> instances between a server using OpenJPA and a client that does not have
> access to enhanced classes or OpenJPA libraries. In some cases, however,
you
> can make the persist and attach processes more robust and efficient by
> allowing breaks in serialization compatibility. See Section
>
<http://openjpa.apache.org/docs/openjpa-0.9.0-incubating/manual/manual.html#
> ref_guide_detach_graph>  1.3, " Defining the Detached Object Graph " for
> details.
>
>
>
> However, in actual practice I have not been able to make this work.  When
I
> have a class structure like:
>
>
>
> @Entity
>
> public class User {
>
>
>
>             @Id
>
>             private String userId;
>
>
>
>             @Column(nullable=false)
>
>             private String password;
>
>
>
>             @ManyToMany
>
>             @JoinTable(name="UserRoles",
>
>                         joinColumn=@JoinColumn(name="userId",
> refererencedColumName="userId"),
>
>                         inverseJoinColumns=@JoinColumn(name="rolename",
> referencedColumnName="roleName"))
>
>             List<Role>  roles;
>
>
>
> }
>
>
>
> @Entity
>
> public class Role {
>
>
>
>             @Id
>
>             private String roleName;
>
>
>
> }
>
>
>
> and I enhance these classes, the enhancer adds into the User.class file an
> additional object of type
org.apache.openjpa.util.java$util$ArrayList$proxy
>
> which actually wrapps the 'roles' field.  Additionally, all of the actual
> field attributes are encapsulated inside another object called 'default'.
I
> can't seem to serialize in any manner that will work,  either with
> ObjectOutputStream, java.beans.XMLEncoder or XStream.toXML,
>
>
>
> When an attempt is made to deserialize in another JVM that does not have
the
> enhanced classes, and does not have the openjpa package at all, it fails.
> Straight ObjectOutputStream fails with class not found for the above
> ArrayList$proxy, XMLCoder generates NullPointerExceptions because it can't
> find the class, and XMLStream doesn't recognized either the class or the
> 'default' tag that was generated on the server side.
>
>
>
> I tried adding in the
>
>
>
> @DetachedState private Object state
>
>
>
> but that doesn't seem to do anything but add an additional field that gets
> filled with a byte array.
>
>
>
>
>
> The XML that is provided by java.beans.XMLEncode which shows the location
of
> the proxy object is:
>
>
>
> <?xml version="1.0" encoding="UTF-8"?>
> <java version="1.6.0" class="java.beans.XMLDecoder">
>  <object class="commons.UserProfile">
>   <void property="emailAddress">
>    <string></string>
>   </void>
>   <void property="firstName">
>    <string>System</string>
>   </void>
>   <void property="lastName">
>    <string>Administrator</string>
>   </void>
>   <void property="password">
>    <string>d69ea425c1a1ad4043f915887f9cd562</string>
>   </void>
>   <void property="phoneNumber">
>    <string></string>
>   </void>
>   <void property="roles">
>    <object class="org.apache.openjpa.util.java$util$ArrayList$proxy">
>     <void method="add">
>      <object id="Role0" class="commons.Role">
>       <void property="roleName">
>        <string>player</string>
>       </void>
>      </object>
>     </void>
>     <void method="add">
>      <object id="Role1" class="commons.Role">
>       <void property="roleName">
>        <string>dungeonmaster</string>
>       </void>
>      </object>
>     </void>
>     <void method="add">
>      <object idref="Role0"/>
>     </void>
>     <void method="add">
>      <object idref="Role1"/>
>     </void>
>    </object>
>   </void>
>   <void property="userId">
>    <string>admin</string>
>   </void>
>  </object>
> </java>
>
>
> So how do you actually implement serialization from an enhanced server
side
> object to a non-enhanced client side object?
>
>
>
>


-- 
Patrick Linskey
202 669 5907

Re: Serialization between ehanced and non-enhanced objects

Posted by Patrick Linskey <pl...@gmail.com>.
Hi,

It sounds like our proxy list wrappers are not exernalizing themselves
properly in your environment. What version of OpenJPA are you using?
Also, can you post your class file itself so that we can take a closer
look at it? Also, can you post your OpenJPA configuration settings?

-Patrick

On 6/27/07, Jere McDevitt <je...@alltel.net> wrote:
> The documentation makes the following claim:
>
>
>
>
> 2.4.  Serializing Enhanced Types
>
>
> By default, OpenJPA maintains serialization compatibility between the
> enhanced and unenhanced versions of a class. This allows you to serialize
> instances between a server using OpenJPA and a client that does not have
> access to enhanced classes or OpenJPA libraries. In some cases, however, you
> can make the persist and attach processes more robust and efficient by
> allowing breaks in serialization compatibility. See Section
> <http://openjpa.apache.org/docs/openjpa-0.9.0-incubating/manual/manual.html#
> ref_guide_detach_graph>  1.3, " Defining the Detached Object Graph " for
> details.
>
>
>
> However, in actual practice I have not been able to make this work.  When I
> have a class structure like:
>
>
>
> @Entity
>
> public class User {
>
>
>
>             @Id
>
>             private String userId;
>
>
>
>             @Column(nullable=false)
>
>             private String password;
>
>
>
>             @ManyToMany
>
>             @JoinTable(name="UserRoles",
>
>                         joinColumn=@JoinColumn(name="userId",
> refererencedColumName="userId"),
>
>                         inverseJoinColumns=@JoinColumn(name="rolename",
> referencedColumnName="roleName"))
>
>             List<Role>  roles;
>
>
>
> }
>
>
>
> @Entity
>
> public class Role {
>
>
>
>             @Id
>
>             private String roleName;
>
>
>
> }
>
>
>
> and I enhance these classes, the enhancer adds into the User.class file an
> additional object of type org.apache.openjpa.util.java$util$ArrayList$proxy
>
> which actually wrapps the 'roles' field.  Additionally, all of the actual
> field attributes are encapsulated inside another object called 'default'.  I
> can't seem to serialize in any manner that will work,  either with
> ObjectOutputStream, java.beans.XMLEncoder or XStream.toXML,
>
>
>
> When an attempt is made to deserialize in another JVM that does not have the
> enhanced classes, and does not have the openjpa package at all, it fails.
> Straight ObjectOutputStream fails with class not found for the above
> ArrayList$proxy, XMLCoder generates NullPointerExceptions because it can't
> find the class, and XMLStream doesn't recognized either the class or the
> 'default' tag that was generated on the server side.
>
>
>
> I tried adding in the
>
>
>
> @DetachedState private Object state
>
>
>
> but that doesn't seem to do anything but add an additional field that gets
> filled with a byte array.
>
>
>
>
>
> The XML that is provided by java.beans.XMLEncode which shows the location of
> the proxy object is:
>
>
>
> <?xml version="1.0" encoding="UTF-8"?>
> <java version="1.6.0" class="java.beans.XMLDecoder">
>  <object class="commons.UserProfile">
>   <void property="emailAddress">
>    <string></string>
>   </void>
>   <void property="firstName">
>    <string>System</string>
>   </void>
>   <void property="lastName">
>    <string>Administrator</string>
>   </void>
>   <void property="password">
>    <string>d69ea425c1a1ad4043f915887f9cd562</string>
>   </void>
>   <void property="phoneNumber">
>    <string></string>
>   </void>
>   <void property="roles">
>    <object class="org.apache.openjpa.util.java$util$ArrayList$proxy">
>     <void method="add">
>      <object id="Role0" class="commons.Role">
>       <void property="roleName">
>        <string>player</string>
>       </void>
>      </object>
>     </void>
>     <void method="add">
>      <object id="Role1" class="commons.Role">
>       <void property="roleName">
>        <string>dungeonmaster</string>
>       </void>
>      </object>
>     </void>
>     <void method="add">
>      <object idref="Role0"/>
>     </void>
>     <void method="add">
>      <object idref="Role1"/>
>     </void>
>    </object>
>   </void>
>   <void property="userId">
>    <string>admin</string>
>   </void>
>  </object>
> </java>
>
>
> So how do you actually implement serialization from an enhanced server side
> object to a non-enhanced client side object?
>
>
>
>


-- 
Patrick Linskey
202 669 5907