Dave,
I've sent you some unit tests offlist that I was using for testing
serialization when I had problems with it.
Note that testSerializationOfDataContextWithNewObject does not pass.
The other two may or may not pass for you -- I have defined my own
equality method for DataObjects.
However, this should give you a good starting point for trying to test
serialization separately from everything else.
Here's what I use for equality in my base DataObject superclass.
protected static boolean safeEquals(Object A, Object B) {
return (A == null) ? (B == null) : A.equals(B);
}
public boolean equals(Object obj)
{
if (obj != null && (obj.getClass().equals(this.getClass())))
{
BaseDataObjectImpl other = (BaseDataObjectImpl)obj;
if (false == safeEquals(objectId, other.getObjectId()))
return false;
return true;
}
return false;
}
public int hashCode ()
{
// This meets requirements (1) and (2). You always return the
// same value for each object because you always return the
// same value for all objects. You also return identical
// hashCode values when two objects test as equals because
// you always return identical hashCode values. There is no
// requirement to return different hashCode values when
// two objects test as not equal.
//
// The only real problem with this implementation is that it
// is an almost totally useless implementation of hashCode.
// It can turn a Hashtable lookup into a linear search.
//
// With JDK 1.1 you can't return 'x', because it can change
// and the requirements for hashCode are that the same value
// must be returned each time hashCode is called on the same object.
//
// Java 2 (formerly JDK 1.2) allows 'return x'; because Java 2
allows the hashCode
// value to change if the underlying data changes. This is more
// friendly, but still allows data to be lost in hashtables
// if the underlying hashCode value changes.
//
return 0;
}
Here's some other serialization stuff. Dont' know if it'll be helpful
for you. I mark my temporary data context with the "temporary" user
property. A lot of this code isn't really used anymore, though.
////// Serialization
private void writeObject(java.io.ObjectOutputStream out)
throws IOException
{
Logger logger = Logger.getLogger("serialization");
if (null == this.getDataContext())
{
logger.info("writeObject: " + this.getClass().getName() + "
[" + String.valueOf(this.hashCode()) + "] has no DC.");
logger.info("writeObject: " + this);
Thread.dumpStack();
}
out.writeBoolean(Boolean.TRUE ==
this.getDataContext().getUserProperty("temporary"));
out.defaultWriteObject();
if (Boolean.TRUE == this.getDataContext().getUserProperty("temporary"))
{
logger.info("writeObject: " + this.getClass().getName() + "
[" + String.valueOf(this.hashCode()) + "] has DC [" +
String.valueOf(this.getDataContext().hashCode()) + "] and is marked
temporary.");
}
else
{
logger.info("writeObject: " + this.getClass().getName() + "
[" + String.valueOf(this.hashCode()) + "] has DC [" +
String.valueOf(this.getDataContext().hashCode()) + "] and is not
marked temporary.");
}
}
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException
{
boolean isInTemporaryDataContext = in.readBoolean();
in.defaultReadObject();
this.isInTemporaryDataContext = isInTemporaryDataContext;
Logger logger = Logger.getLogger("serialization");
if (null != this.getDataContext())
{
if (isInTemporaryDataContext)
{
logger.info("readObject: " + this.getClass().getName() +
" [" + String.valueOf(this.hashCode()) + "] has DC [" +
String.valueOf(this.getDataContext().hashCode()) + "] and is marked
temporary.");
}
else
{
logger.info("readObject: " + this.getClass().getName() +
" [" + String.valueOf(this.hashCode()) + "] has DC [" +
String.valueOf(this.getDataContext().hashCode()) + "] and is not
marked temporary.");
}
}
else
{
if (isInTemporaryDataContext)
{
logger.info("readObject: " + this.getClass().getName() +
" [" + String.valueOf(this.hashCode()) + "] has no DC and is marked
temporary.");
}
else
{
logger.info("readObject: " + this.getClass().getName() +
" [" + String.valueOf(this.hashCode()) + "] has no DC and is not
marked temporary.");
}
}
}
/**
* Substitute self with an object registered in thread
* DataContext with the same ID.
*/
protected Object readResolve() throws ObjectStreamException
{
if (null == getDataContext())
{
if (isInTemporaryDataContext)
{
Logger logger = Logger.getLogger("serialization");
logger.info("readResolve: " + this.getClass().getName() +
" [" + String.valueOf(this.hashCode()) + "] has no DC and is marked
temporary.");
return this;
}
else
{
Logger logger = Logger.getLogger("serialization");
logger.info("readResolve: " + this.getClass().getName() +
" [" + String.valueOf(this.hashCode()) + "] has no DC and is not
marked temporary.");
DataContext context;
try {
context = DataContext.getThreadDataContext();
}
catch (IllegalStateException e) {
throw new NotActiveException("Can't deserialize
object for id '"
+ getObjectId()
+ "' - no DataContext bound to thread.");
}
// return context.registeredObject(getObjectId());
return context.localObject(getObjectId(), null);
}
}
else
{
Logger logger = Logger.getLogger("serialization");
logger.info("readResolve: " + this.getClass().getName() + "
[" + String.valueOf(this.hashCode()) + "] has DC [" +
String.valueOf(this.getDataContext().hashCode()) + "].");
return this;
}
}
On 9/11/06, Mike Kienenberger <mkienen..mail.com> wrote:
> No, I wouldn't try changing the transient nature.
>
> It does seem kinda odd, though. I know that I'm saving serialized
> objects two different ways -- by individual DataObject for one
> read-only context, and by DataContext for a modified set of objects.
> I don't think I have seen this particular problem.
>
> Are you serializing the DataContext directly?
>
>
> On 9/11/06, Dave Dombrosky <dombr..mail.com> wrote:
> > I downloaded the 1.2.1 source and added some code to figure out what
> > is going on. It appears that context.getChannel() from
> > ObjectStore.java line 945 is returning null. I am guessing that this
> > is because of DataContext line 182 which declares the channel to be
> > transient. Transient properties are not serialized, which is how
> > tomcat saves the session, so it is reverting back to it's default
> > value (null).
> >
> > I tried removing the "transient" part of the variable declaration, but
> > then Tomcat complains on a different piece of code. I'm not even sure
> > if that's the best way to fix it so I don't think I'll explore that
> > any further yet. Is this issue something that I should add to JIRA?
> >
> > -Dave
> >
> > On 9/11/06, Mike Kienenberger <mkienen..mail.com> wrote:
> > > My suggestion would be to look at the 1.2.1 source and see what's
> > > going on at ObjectStore.java, line 945.
> > >
> > > On 9/11/06, Dave Dombrosky <dombr..mail.com> wrote:
> > > > Problem still occurs on 1.2.1
> > > >
> > > > On 9/11/06, Mike Kienenberger <mkienen..mail.com> wrote:
> > > > > Maybe http://issues.apache.org/cayenne/browse/CAY-614 ?
> > > > >
> > > > > This was fixed for 1.2.1. It might be related.
> > > > >
> > > > > On 9/11/06, Dave Dombrosky <dombr..mail.com> wrote:
> > > > > > I am currently having problems when trying to use Cayenne 1.2 along
> > > > > > with Tomcat's (v5.0.28) session restore capability. That is to say,
> > > > > > if I deploy new code and restart tomcat, it saves the session data
> > > > > > instead of starting with all new sessions when it starts up.
> > > > > >
> > > > > > My problem is that I used to be able to restart and stay logged in
> > > > > > using version 1.1. Version 1.2 seems to have problems with trying to
> > > > > > look up data after I have restarted Tomcat, and I get this stack trace
> > > > > > caused by a NullPointerException:
> > > > > >
> > > > > > org.objectstyle.cayenne.access.ObjectStore.resolveHollow(ObjectStore.java:945)
> > > > > > org.objectstyle.cayenne.access.DataContext.prepareForAccess(DataContext.java:1842)
> > > > > > org.objectstyle.cayenne.CayenneDataObject.readProperty(CayenneDataObject.java:238)
> > > > > >
> > > > > > I couldn't find anyone else with this problem, so I assume I am doing
> > > > > > something wrong and it's not a bug. Any ideas?
> > > > > >
> > > > > > -Dave
> > > > > >
> > > > >
> > > >
> > >
> >
>
This archive was generated by hypermail 2.0.0 : Mon Sep 11 2006 - 17:03:12 EDT