[CDBI] Deep recursion on subroutine "Class::DBI::_flesh"

Dan Fisher dan at askingforthirds.org
Thu Jan 26 17:07:42 GMT 2006


I had been running into this error (under CDBI 3.0.14):

Deep recursion on subroutine "Class::DBI::_flesh" at
/usr/lib/perl5/site_perl/5.8.5/Class/DBI.pm line 837.
Deep recursion on anonymous subroutine at
/usr/lib/perl5/site_perl/5.8.5/Class/DBI.pm line 849.

and while I saw this referenced earlier on the mailing list, my problem did
not stem from triggers, so I had to go out on my own to solve it.

First, a program that demonstrates the error:
----------------------------------------------------------------------------------------------------------------
#!/usr/bin/perl

use strict;

package Person;

# Schema:
# CREATE TABLE test_table ( id integer not null primary key auto_increment,
name varchar(254) );

use base qw/Class::DBI/;

__PACKAGE__->connection('dbi:mysql:test', 'test', '12345', {AutoCommit => 1,
RaiseError => 1, PrintError => 1});
__PACKAGE__->table('test_table');
__PACKAGE__->columns( Primary => qw/
        id
/);
__PACKAGE__->columns( All => qw/
        id
        name
/);

package main;

my $person_1 = Person->insert({});
print $person_1->name."\n";
$person_1->delete();

print '$person_1 created and deleted'."\n";

my $person_2 = Person->construct();
print $person_2->name."\n";

print '$person_2 created and accessed'."\n";
print 'Program Completed'."\n";
----------------------------------------------------------------------------------------------------------------

When I run this, I get the following results:

$person_1 created and deleted
Deep recursion on subroutine "Class::DBI::_flesh" at
/usr/lib/perl5/site_perl/5.8.5/Class/DBI.pm line 837.
Deep recursion on anonymous subroutine at
/usr/lib/perl5/site_perl/5.8.5/Class/DBI.pm line 849.

...
and the program never finishes.

----------------------------------------------------------------------------------------------------------------
I've found that the problem is that the 'get' method doesn't have any idea
about what columns it can potentially grab... While this is set up in
'insert/create', it is not set up in 'construct'. Now this might be by
design, but I really like to have an object (with all the methods already
written) without necessarily inserting it into the DB, and 'construct' seems
to be the way to get that object.

My solution is primitive and I'll bet it could be optimized using the CDBI
internal API:
In 'Person' override the 'construct' method like this:

sub construct {
        my $class = shift;
        my $value_href = shift;
        my $no_value_href = {map {$_ => ''} $class->columns};
        my $self = $class->SUPER::construct($no_value_href);

        my %value_hash = %{$value_href} if $value_href;
        $self->set(%value_hash);
        return $self;
}

Now, *all* the columns are initialized... Not just the ones sent values, and
the program above will finish.

Any thoughts on this? Do I need to put this method in a base class that alll
CDBI classes will inherit from or is there any chance that this behavior can
be integrated into CDBI-proper?

Thank you for your time,
Daniel Fisher
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.digitalcraftsmen.net/mailman/private/classdbi/attachments/20060126/d2c38065/attachment.html


More information about the ClassDBI mailing list