This one time, at band camp, Rhett Sutphin said:
RS>Hi,
RS>
RS>I wrote:
RS>> The problem arises because JDO uses methods in SQLEngine and
RS>> SQLRelationLoader to do type conversion. The XML side uses the
RS>> FieldHandler to do it. As you can see from the modifications list
RS>> above, I've been trying to remove the SQL* involvement in type
RS>> conversion. Unfortunately, this doesn't work in this case. I had to
RS>> put this on the back burner for a couple of weeks, but IIRC, making
RS>> SQLRelationLoader's converter methods into no-ops causes the same
RS>> problem on a different set of test cases. The problem seems to arise
RS>> out of special-case handling of the id field(s) in certain
RS>> circumstances that I don't yet grok.
RS>
RS>I have a better understanding of the problem now, so maybe I can
RS>explain it in a way that Bruce (or someone else) can recommend a
RS>solution.
RS>
RS>The problem arises from the fact that FieldHandlerImpl's getValue and
RS>setValue methods always apply the contained TypeConvertor to their
RS>input/output. The effect of this JDO-wise is that getValue always
RS>returns the value in the "SQL" type. So the value the engine is using
RS>to check against the cache is, e.g., a BigDecimal instead of an
RS>Integer. (FieldMolder doesn't do this -- it returns the value in its
RS>java type and the persistence classes convert it to SQL just before it
RS>is stored.)
RS>
RS>Since it is a consistent change, it seems like it shouldn't matter --
RS>all the fields will be manipulated by the persisting classes in
RS>SQL-type space instead of java-type space. (Maybe this is an overly
RS>simplistic analysis -- let me know if so.) But a conflict arises when
RS>an object is created or loaded with an explicit key field, manipulated,
RS>and then persisted (back) to the database. The type of the id field
RS>changes when it goes through the MappingFieldMolder during the
RS>manipulation, so there's a PersistenceException about unequal ids.
RS>
RS>I've been trying to come up with a way to fix this from the FieldMolder
RS>side, but haven't been successful. The only solution I have thought up
RS>is to convert the identity in TransactionContext (in load, create, ?)
RS>before the first time an object is registered in the cache. This seems
RS>sort of invasive to me though, so I thought I'd ask for other
RS>suggestions first.
Rhett,
My apologies for the delayed repsonse. Life happens.
Since you've had to make so many changes to the code base, please send me
a tarball of the files you've changed. I'm attaching a Perl script that
will automatically create a tarball of the diffs that you can send to me.
Bruce
--
perl -e 'print unpack("u30","<0G)U8V4\@4VYY9&5R\"F9E<G)E=\$\!F<FEI+F-O;0\`\`");'
#!/usr/bin/perl -w
##############################################################################
# diff2tb.pl
#
# Description:
# From a CVS brief diff of a working dir, this script creates a tarball
# of all files that have been changed. It's useful for creating a tarball
# of changes to someone to be applied to their working dir.
#
# NOTE:
# Not yet tested on Windoze.
#
# Auhtor:
# Bruce Snyder, [EMAIL PROTECTED], 10 Dec 2002
##############################################################################
use Archive::Tar;
use File::Path;
use strict;
my $diff = time() . "-cvsbrief.diff";
system( "cvs -q diff --brief > $diff" );
open( DIFF, $diff ) || die "Unable to open $diff!";
my $tar = Archive::Tar->new() || die "Unable to create tar archive: $!\n";
my $tarball = "changes.tar.gz";
if ( -e $tarball )
{
rmtree( $tarball, 0, 1 );
}
my @files = ();
while( <DIFF> )
{
if( s/Index: // )
{
chomp();
$tar->add_files( glob );
}
}
$tar->write( $tarball, 1 ) || die "Unable to create tarball: $!\n";
# For debugging only
# print join( "\n", $tar->list_files( $tarball ) );
# print "\n";
close( DIFF );