[Dbix-class] Re: create_related is failing on second time through loop?

Ben Tilly btilly at gmail.com
Thu Jun 21 19:46:45 GMT 2012


You are inserting two different records with the same detail_id into a
table named detail that likely has a primary key on detail_id.

I suspect that in your test script you wanted to set header_id to 5,
not detail_id.

On Thu, Jun 21, 2012 at 11:31 AM, Tim Anderson <tja824 at gmail.com> wrote:
> I've reduced my issue to a simple test scenario and I am still able to
> reproduce.  Here's what I've got:
>
>   A 'header' table, with a header_id column (pk) and a header_name column.
>   A 'detail' table, with a header_id and detail_id column (pk) and a detail
> name column.
>
> I generated the Schema files for my simple database using the Schema::Loader
> module.  Then I wrote the following test script:
>
> #!/usr/bin/perl
>
> use lib ('./lib');
> use TJATest::Schema;
>
> my $schema = TJATest::Schema->connect(
> 'dbi:Sybase:server=mgmtDb;database=tja_test',
>                                        'xxxxxxxx', 'xxxxxxxx' );
> $schema->storage->debug(1);
>
> my $rs = $schema->resultset('Header');
> my $loop_counter = 1;
> while (my $row = $rs->next) {
>   print "\n\nLOOP $loop_counter\n";
>   print $row->header_name . "\n";
>
>   $row->create_related ('details', { detail_id => 5, detail_name => 'new
> detail (five)' } );
>   $loop_counter += 1;
> }
>
>
> There are 3 rows in the Header table, so there will be 3 executions of the
> code in the while loop.  However, when I run the script, I get the following
> output:
>
> ~/dbix$ ./test.pl
> SELECT me.header_id, me.header_name FROM header me:
>
>
> LOOP 1
> header one
> INSERT INTO detail ( detail_id, detail_name, header_id) VALUES ( ?, ?, ? )
> SELECT SCOPE_IDENTITY(): '5', 'new detail (five)', '1'
>
>
> LOOP 2
> header two
> INSERT INTO detail ( detail_id, detail_name, header_id) VALUES ( ?, ?, ? )
> SELECT SCOPE_IDENTITY(): '5', 'new detail (five)', '2'
> DBIx::Class::Relationship::Base::create_related(): Unknown error: execute()
> returned false, but error flags were not set... at ./test.pl line 16
>
>
> During loop 1, the detail row is successfully created.  During loop 2,
> however, I get an error, and the second record is not inserted.
>
> The exception (above) is thrown out of the DBIx/Class/Storage/DBI.pm module,
> at line 1593 (my $rv = $sth->execute();).  I've run this with the perl
> debugger, and tried to see what might be different in the $sth between loop
> 1 and loop 2, but I just don't see it.
>
> Has anyone encountered this before, and/or have any ideas of where to go
> next?
>
> I installed the system this is running on on 6/15, with current CPAN modules
> at that time.
>
>
> -Tim
>
>
>
> On Tue, Jun 19, 2012 at 12:22 PM, Tim Anderson <tja824 at gmail.com> wrote:
>>
>>
>>>
>>> Greetings,
>>>
>>> I've been working with DBIx::Class/Catalyst for about 2 months, and up
>>> until yesterday I was feeling pretty good about my proficiency... long way
>>> to go, though.  I have been doing my development in a VirtualBox VM on my
>>> workstation and arrived at a point where I wanted to move my application to
>>> it's new home.  I set up the new server, installed the necessary Perl
>>> modules via CPAN, and copied over my application.  Most of it works.
>>>
>>> I have two tables, one with a has_many relationship to the other. My
>>> application needs to take some posted data, updates a single record in the
>>> main table, and then deletes and re-adds a variable number of records for
>>> the 'has many' table.  When the variable number <= 1, all is well, but if
>>> the number is >1, the first record gets inserted in the table and then I get
>>> the following in my server output:
>>>
>>> [error] DBIx::Class::Relationship::Base::create_related(): Unknown error:
>>> execute() returned false, but error flags were not set... at
>>> /opt/lms/catalyst/Portal/script/../lib/Portal/Controller/Users.pm line 429
>>>
>>>
>>> The code in question:
>>>
>>>    #handle user_roles
>>>    my $roles = $c->request->params->{'user_role'};  #this is what is
>>> desired
>>>    $roles = [ $roles ] if ref ($roles) ne 'ARRAY';
>>>
>>>       my $existing_record = $c->model('DB::' .
>>> $package_name)->has_record(\%form_key_vals);
>>>
>>>    if (defined ($existing_record)) {
>>>
>>>      $existing_record = $existing_record->update(\%form_vals);  #this is
>>> working
>>>
>>>      # Delete user's existing roles, then add the new ones
>>>      $c->model('DB::PortalUserRole')->search({ client_id =>
>>> $form_vals{client_id},
>>>                                                user_id =>
>>> $form_vals{user_id}, })->delete;  #this is working
>>>
>>>      foreach my $new_role (@{$roles}) {
>>>        $c->log->debug("Creating new role: " . Dumper($new_role));
>>>
>>>        $existing_record->create_related ('portal_user_roles', { role_id
>>> => $new_role });  #first time through works, but fails on second pass
>>>      }
>>>
>>>    }
>>>
>>> When I set DBIC_TRACE=1, I see the following stack trace:
>>>
>>>
>>> DBIx::Class::Schema::throw_exception('Portal::Schema=HASH(0x35fd380)',
>>> 'Unknown error: execute() returned false, but error flags were...') called
>>> at /usr/local/share/perl5/DBIx/Class/Storage.pm line 111
>>>
>>> DBIx::Class::Storage::throw_exception('DBIx::Class::Storage::DBI::Sybase::Microsoft_SQL_Server::Free...',
>>> 'Unknown error: execute() returned false, but error flags were...') called
>>> at /usr/local/share/perl5/DBIx/Class/Storage/DBI.pm line 1594
>>>
>>> DBIx::Class::Storage::DBI::_dbh_execute('DBIx::Class::Storage::DBI::Sybase::Microsoft_SQL_Server::Free...',
>>> 'DBI::db=HASH(0x51679a0)', 'INSERT INTO PORTAL_USER_ROLE ( client_id,
>>> role_id, user_id) V...', 'ARRAY(0x4fa0490)', 'ARRAY(0x533ea30)') called at
>>> /usr/local/share/perl5/DBIx/Class/Storage/DBI.pm line 789
>>>         DBIx::Class::Storage::DBI::__ANON__() called at
>>> /usr/local/share/perl5/Try/Tiny.pm line 71
>>>         eval {...} called at /usr/local/share/perl5/Try/Tiny.pm line 67
>>>         Try::Tiny::try('CODE(0x533e880)',
>>> 'Try::Tiny::Catch=REF(0x520def8)') called at
>>> /usr/local/share/perl5/DBIx/Class/Storage/DBI.pm line 800
>>>         DBIx::Class::Storage::DBI::dbh_do(undef, undef, 'INSERT INTO
>>> PORTAL_USER_ROLE ( client_id, role_id, user_id) V...', 'ARRAY(0x4fa0490)',
>>> 'ARRAY(0x533ea30)') called at
>>> /usr/local/share/perl5/DBIx/Class/Storage/DBI.pm line 1558
>>>
>>> DBIx::Class::Storage::DBI::_execute('DBIx::Class::Storage::DBI::Sybase::Microsoft_SQL_Server::Free...',
>>> 'insert', 'DBIx::Class::ResultSource::Table=HASH(0x4943810)',
>>> 'HASH(0x534d2d8)', undef) called at
>>> /usr/local/share/perl5/DBIx/Class/Storage/DBI/MSSQL.pm line 116
>>>
>>> DBIx::Class::Storage::DBI::MSSQL::_execute('DBIx::Class::Storage::DBI::Sybase::Microsoft_SQL_Server::Free...',
>>> 'insert', 'DBIx::Class::ResultSource::Table=HASH(0x4943810)',
>>> 'HASH(0x534d2d8)', undef) called at
>>> /usr/local/share/perl5/DBIx/Class/Storage/DBI.pm line 1671
>>>
>>> DBIx::Class::Storage::DBI::insert('DBIx::Class::Storage::DBI::Sybase::Microsoft_SQL_Server::Free...',
>>> 'DBIx::Class::ResultSource::Table=HASH(0x4943810)', 'HASH(0x4f9b328)')
>>> called at /usr/local/share/perl5/DBIx/Class/Storage/DBI/MSSQL.pm line 67
>>>
>>> DBIx::Class::Storage::DBI::MSSQL::insert('DBIx::Class::Storage::DBI::Sybase::Microsoft_SQL_Server::Free...',
>>> 'DBIx::Class::ResultSource::Table=HASH(0x4943810)', 'HASH(0x4f9b328)')
>>> called at /usr/local/share/perl5/DBIx/Class/Row.pm line 350
>>>
>>> DBIx::Class::Row::insert('Portal::Model::DB::PortalUserRole=HASH(0x4fa0790)')
>>> called at /usr/local/share/perl5/DBIx/Class/Relationship/Base.pm line 604
>>>
>>> DBIx::Class::Relationship::Base::create_related('Portal::Model::DB::PortalUser=HASH(0x533ea78)',
>>> 'portal_user_roles', 'HASH(0x4f9b130)') called at
>>> /opt/lms/catalyst/Portal/script/../lib/Portal/Controller/Users.pm line 443
>>>
>>> Portal::Controller::Users::save('Portal::Controller::Users=HASH(0x4c14790)',
>>> 'Portal=HASH(0x4f7fc98)') called at
>>> /usr/local/share/perl5/Catalyst/Action.pm line 65
>>>         Catalyst::Action::execute('Catalyst::Action=HASH(0x4df5890)',
>>> 'Portal::Controller::Users=HASH(0x4c14790)', 'Portal=HASH(0x4f7fc98)')
>>> called at /usr/local/share/perl5/Catalyst.pm line 1668
>>>         eval {...} called at /usr/local/share/perl5/Catalyst.pm line 1668
>>>         Catalyst::execute('Portal=HASH(0x4f7fc98)',
>>> 'Portal::Controller::Users', 'Catalyst::Action=HASH(0x4df5890)') called at
>>> /usr/local/share/perl5/Catalyst/Plugin/StackTrace.pm line 94
>>>         Catalyst::Plugin::StackTrace::execute('Portal=HASH(0x4f7fc98)',
>>> 'Portal::Controller::Users', 'Catalyst::Action=HASH(0x4df5890)') called at
>>> /usr/local/share/perl5/Catalyst/Action.pm line 60
>>>         Catalyst::Action::dispatch('Catalyst::Action=HASH(0x4df5890)',
>>> 'Portal=HASH(0x4f7fc98)') called at
>>> /usr/local/share/perl5/Catalyst/ActionChain.pm line 38
>>>
>>> Catalyst::ActionChain::dispatch('Catalyst::ActionChain=HASH(0x4f83db8)',
>>> 'Portal=HASH(0x4f7fc98)') called at
>>> /usr/local/share/perl5/Catalyst/Controller.pm line 125
>>>
>>> Catalyst::Controller::_ACTION('Portal::Controller::Users=HASH(0x4c14790)',
>>> 'Portal=HASH(0x4f7fc98)') called at
>>> /usr/local/share/perl5/Catalyst/Action.pm line 65
>>>         Catalyst::Action::execute('Catalyst::Action=HASH(0x4dee848)',
>>> 'Portal::Controller::Users=HASH(0x4c14790)', 'Portal=HASH(0x4f7fc98)')
>>> called at /usr/local/share/perl5/Catalyst.pm line 1668
>>>         eval {...} called at /usr/local/share/perl5/Catalyst.pm line 1668
>>>         Catalyst::execute('Portal=HASH(0x4f7fc98)',
>>> 'Portal::Controller::Users', 'Catalyst::Action=HASH(0x4dee848)') called at
>>> /usr/local/share/perl5/Catalyst/Plugin/StackTrace.pm line 94
>>>         Catalyst::Plugin::StackTrace::execute('Portal=HASH(0x4f7fc98)',
>>> 'Portal::Controller::Users', 'Catalyst::Action=HASH(0x4dee848)') called at
>>> /usr/local/share/perl5/Catalyst/Action.pm line 60
>>>         Catalyst::Action::dispatch('Catalyst::Action=HASH(0x4dee848)',
>>> 'Portal=HASH(0x4f7fc98)') called at
>>> /usr/local/share/perl5/Catalyst/Dispatcher.pm line 257
>>>
>>> Catalyst::Dispatcher::_do_forward('Catalyst::Dispatcher=HASH(0x21c9488)',
>>> 'forward', 'Portal=HASH(0x4f7fc98)', '_ACTION') called at
>>> /usr/local/share/perl5/Catalyst/Dispatcher.pm line 237
>>>
>>> Catalyst::Dispatcher::forward('Catalyst::Dispatcher=HASH(0x21c9488)',
>>> 'Portal=HASH(0x4f7fc98)', '_ACTION') called at
>>> /usr/local/share/perl5/Catalyst.pm line 358
>>>         Catalyst::forward('Portal=HASH(0x4f7fc98)', '_ACTION') called at
>>> /usr/local/share/perl5/Catalyst/Controller.pm line 99
>>>
>>> Catalyst::Controller::_DISPATCH('Portal::Controller::Users=HASH(0x4c14790)',
>>> 'Portal=HASH(0x4f7fc98)') called at
>>> /usr/local/share/perl5/Catalyst/Action.pm line 65
>>>         Catalyst::Action::execute('Catalyst::Action=HASH(0x4dee560)',
>>> 'Portal::Controller::Users=HASH(0x4c14790)', 'Portal=HASH(0x4f7fc98)')
>>> called at /usr/local/share/perl5/Catalyst.pm line 1668
>>>         eval {...} called at /usr/local/share/perl5/Catalyst.pm line 1668
>>>         Catalyst::execute('Portal=HASH(0x4f7fc98)',
>>> 'Portal::Controller::Users', 'Catalyst::Action=HASH(0x4dee560)') called at
>>> /usr/local/share/perl5/Catalyst/Plugin/StackTrace.pm line 94
>>>         Catalyst::Plugin::StackTrace::execute('Portal=HASH(0x4f7fc98)',
>>> 'Portal::Controller::Users', 'Catalyst::Action=HASH(0x4dee560)') called at
>>> /usr/local/share/perl5/Catalyst/Action.pm line 60
>>>         Catalyst::Action::dispatch('Catalyst::Action=HASH(0x4dee560)',
>>> 'Portal=HASH(0x4f7fc98)') called at
>>> /usr/local/share/perl5/Catalyst/Dispatcher.pm line 257
>>>
>>> Catalyst::Dispatcher::_do_forward('Catalyst::Dispatcher=HASH(0x21c9488)',
>>> 'forward', 'Portal=HASH(0x4f7fc98)', '/users/_DISPATCH') called at
>>> /usr/local/share/perl5/Catalyst/Dispatcher.pm line 237
>>>
>>> Catalyst::Dispatcher::forward('Catalyst::Dispatcher=HASH(0x21c9488)',
>>> 'Portal=HASH(0x4f7fc98)', '/users/_DISPATCH') called at
>>> /usr/local/share/perl5/Catalyst.pm line 358
>>>         Catalyst::forward('Portal=HASH(0x4f7fc98)', '/users/_DISPATCH')
>>> called at /usr/local/share/perl5/Catalyst/Dispatcher.pm line 105
>>>
>>> Catalyst::Dispatcher::dispatch('Catalyst::Dispatcher=HASH(0x21c9488)',
>>> 'Portal=HASH(0x4f7fc98)') called at /usr/local/share/perl5/Catalyst.pm line
>>> 1614
>>>         Catalyst::dispatch('Portal=HASH(0x4f7fc98)') called at
>>> /usr/local/share/perl5/Catalyst/Plugin/Static/Simple.pm line 77
>>>         Class::MOP::Class:::around('CODE(0x284fba8)',
>>> 'Portal=HASH(0x4f7fc98)') called at
>>> /usr/local/lib64/perl5/Class/MOP/Method/Wrapped.pm line 162
>>>         Class::MOP::Method::Wrapped::__ANON__('Portal=HASH(0x4f7fc98)')
>>> called at /usr/local/lib64/perl5/Class/MOP/Method/Wrapped.pm line 91
>>>         Portal::dispatch('Portal=HASH(0x4f7fc98)') called at
>>> /usr/local/share/perl5/Catalyst.pm line 1964
>>>         Catalyst::__ANON__() called at /usr/local/share/perl5/Try/Tiny.pm
>>> line 76
>>>         eval {...} called at /usr/local/share/perl5/Try/Tiny.pm line 67
>>>         Try::Tiny::try('CODE(0x4f616a0)',
>>> 'Try::Tiny::Catch=REF(0x4ecac50)') called at
>>> /usr/local/share/perl5/Catalyst.pm line 1970
>>>         Catalyst::handle_request('Portal', 'env', 'HASH(0x4f58460)',
>>> 'response_cb', 'CODE(0x4f61340)') called at
>>> /usr/local/share/perl5/Catalyst/Engine.pm line 682
>>>         Catalyst::Engine::__ANON__('CODE(0x4f61340)') called at
>>> /usr/local/share/perl5/Plack/Handler/FCGI.pm line 137
>>>         Plack::Handler::FCGI::run('Plack::Handler::FCGI=HASH(0x28ff9a0)',
>>> 'CODE(0x49086f8)', 'HASH(0x218b718)') called at
>>> /usr/local/share/perl5/Catalyst/Engine.pm line 664
>>>         Catalyst::Engine::run('Catalyst::Engine=HASH(0x2e0c958)',
>>> 'Portal', 'CODE(0x49086f8)', '/opt/lms/catalyst/sockets/portal.socket',
>>> 'HASH(0x218b718)', 'Plack::Handler::FCGI=HASH(0x28ff9a0)') called at
>>> /usr/local/share/perl5/Catalyst.pm line 2427
>>>         Catalyst::run('Portal',
>>> '/opt/lms/catalyst/sockets/portal.socket', 'HASH(0x218b718)',
>>> 'Plack::Handler::FCGI=HASH(0x28ff9a0)') called at
>>> /usr/local/share/perl5/Catalyst/ScriptRole.pm line 91
>>>
>>> Catalyst::ScriptRole::_run_application('Catalyst::Script::FastCGI=HASH(0x219e6e8)')
>>> called at /usr/local/share/perl5/Catalyst/ScriptRole.pm line 61
>>>
>>> Catalyst::ScriptRole::run('Catalyst::Script::FastCGI=HASH(0x219e6e8)')
>>> called at /usr/local/share/perl5/Catalyst/ScriptRunner.pm line 50
>>>         Catalyst::ScriptRunner::run('Catalyst::ScriptRunner', 'Portal',
>>> 'FastCGI') called at script/portal_fastcgi.pl line 4
>>>
>>> I've been Googling for the past day and a half, and I've tried several
>>> things to isolate the problem and shed more light, but I am at a standstill.
>>>  Has anyone seen this happen before, to be able to point me toward a
>>> solution?  I've traced on the database side, and I don't even think the
>>> second insert is being run there.  I'd greatly appreciate any help.
>>>
>>> Yes, I realize there are Catalyst dependencies in my code, and I have
>>> asked the question on that list too.  Unfortunately, I'm not comfortable yet
>>> decoupling the DBIx modules from the Catalyst framework, but that's my next
>>> step.
>>>
>>> Thanks in advance.
>>>
>>>
>>>
>>> -Tim
>>
>>
>
>
> _______________________________________________
> List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
> IRC: irc.perl.org#dbix-class
> SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
> Searchable Archive:
> http://www.grokbase.com/group/dbix-class@lists.scsys.co.uk



More information about the DBIx-Class mailing list