Error creating a record when the model has no id column #2334

Closed
dchelimsky opened this Issue Jul 28, 2011 · 17 comments

Projects

None yet

5 participants

@dchelimsky

Here's an edge case for you:

jruby-1.6.3
oracle
rails-3.0.8
activerecord-jdbc-adapter-1.1.2.1

At this point I'm not sure where the problem lies so I'm documenting it here - might be a bug in activerecord, arel, or the activerecord-jdbc-adapter.

Our app has a model with no primary key column (e.g. id). When trying to create a record, I get the following error:

Thing.create!
NoMethodError: undefined method `name' for nil:NilClass
    from org/jruby/RubyKernel.java:238:in `method_missing'
    from /Users/dchelimsky/.rvm/gems/jruby-1.6.3@vera/gems/activesupport-3.0.8/lib/active_support/whiny_nil.rb:48:in `method_missing'
    from /Users/dchelimsky/.rvm/gems/jruby-1.6.3@vera/gems/arel-2.0.10/lib/arel/visitors/to_sql.rb:56:in `visit_Arel_Nodes_InsertStatement'
    from org/jruby/RubyArray.java:2336:in `collect'
    from /Users/dchelimsky/.rvm/gems/jruby-1.6.3@vera/gems/arel-2.0.10/lib/arel/visitors/to_sql.rb:55:in `visit_Arel_Nodes_InsertStatement'
    from org/jruby/RubyKernel.java:2096:in `send'
    from /Users/dchelimsky/.rvm/gems/jruby-1.6.3@vera/gems/arel-2.0.10/lib/arel/visitors/visitor.rb:15:in `visit'
    from /Users/dchelimsky/.rvm/gems/jruby-1.6.3@vera/gems/arel-2.0.10/lib/arel/visitors/visitor.rb:5:in `accept'
    from /Users/dchelimsky/.rvm/gems/jruby-1.6.3@vera/gems/arel-2.0.10/lib/arel/visitors/to_sql.rb:18:in `accept'
    from /Users/dchelimsky/.rvm/gems/jruby-1.6.3@vera/gems/activerecord-3.0.8/lib/active_record/connection_adapters/abstract/connection_pool.rb:111:in `with_connection'
    from /Users/dchelimsky/.rvm/gems/jruby-1.6.3@vera/gems/arel-2.0.10/lib/arel/visitors/to_sql.rb:16:in `accept'
    from /Users/dchelimsky/.rvm/gems/jruby-1.6.3@vera/gems/arel-2.0.10/lib/arel/tree_manager.rb:20:in `to_sql'
    from /Users/dchelimsky/.rvm/gems/jruby-1.6.3@vera/gems/arel-2.0.10/lib/arel/select_manager.rb:217:in `insert'
    from org/jruby/RubyKernel.java:2096:in `send'
    from /Users/dchelimsky/.rvm/gems/jruby-1.6.3@vera/gems/activerecord-3.0.8/lib/active_record/relation.rb:14:in `insert'
    from /Users/dchelimsky/.rvm/gems/jruby-1.6.3@vera/gems/activerecord-3.0.8/lib/active_record/persistence.rb:274:in `create'
... 19 levels...
    from org/jruby/RubyKernel.java:1088:in `eval'
    from /Users/dchelimsky/.rvm/gems/jruby-1.6.3@vera/gems/ruby-debug-0.10.4/cli/ruby-debug/commands/irb.rb:99:in `evaluate'
    from /Users/dchelimsky/.rvm/rubies/jruby-1.6.3/lib/ruby/1.8/irb.rb:158:in `eval_input'
    from /Users/dchelimsky/.rvm/rubies/jruby-1.6.3/lib/ruby/1.8/irb.rb:271:in `signal_status'
    from /Users/dchelimsky/.rvm/rubies/jruby-1.6.3/lib/ruby/1.8/irb.rb:155:in `eval_input'
    from org/jruby/RubyKernel.java:1419:in `loop'
    from org/jruby/RubyKernel.java:1191:in `catch'
    from /Users/dchelimsky/.rvm/rubies/jruby-1.6.3/lib/ruby/1.8/irb.rb:154:in `eval_input'
    from /Users/dchelimsky/.rvm/rubies/jruby-1.6.3/lib/ruby/1.8/irb.rb:71:in `start'
    from org/jruby/RubyKernel.java:1191:in `catch'
    from /Users/dchelimsky/.rvm/rubies/jruby-1.6.3/lib/ruby/1.8/irb.rb:70:in `start'
    from /Users/dchelimsky/.rvm/gems/jruby-1.6.3@vera/gems/railties-3.0.8/lib/rails/commands/console.rb:44:in `start'
    from /Users/dchelimsky/.rvm/gems/jruby-1.6.3@vera/gems/railties-3.0.8/lib/rails/commands/console.rb:8:in `start'
    from /Users/dchelimsky/.rvm/gems/jruby-1.6.3@vera/gems/railties-3.0.8/lib/rails/commands.rb:23:in `(root)'
    from org/jruby/RubyKernel.java:1038:in `require'
    from script/rails:6:in `(root)'jruby-1.6.3

To reproduce:

rails new example
cd example
rails g model things name:string

Update the migration to exclude an id column:

class CreateThings < ActiveRecord::Migration
  def self.up
    create_table :things, :id => false do |t|
      t.string :name

      t.timestamps
    end
  end

  def self.down
    drop_table :things
  end
end

Back to the shell:

rake db:migrate
rails runner "Thing.create"
@dchelimsky

A little more information: at the point that we get to https://github.com/rails/arel/blob/v2.0.10/lib/arel/visitors/to_sql.rb#L55, o.columns contains two items, the latter of which is nil.

@dmathieu

I do not reproduce it using mri 1.9 and sqlite. Neither in master nor in 3-0-stable.

@tenderlove tenderlove was assigned Jul 28, 2011
@dchelimsky

@dmathieu - yes, this is only happening w/ jruby+oracle for me as well.

@tenderlove
Member

I can't for the life of me get Oracle running on my Lion machine. Maybe @rsim can help out? Otherwise, I'm going to need to get access to an Oracle machine (which I can do through work, it will just take time).

@tenderlove
Member

Heh "Oracle Machine".

@eduardordm

@tenderlove 64bit instant client is broken on Lion. 32 bits may work if you are lucky.

@tenderlove
Member

@dchelimsky does it happen with the native oci driver and MRI?

@dchelimsky

@tenderlove - nope - just activerecord-jdbc-adapter + jruby.

@tenderlove
Member

Yikes. Okay, I just (today) gained access to a machine with that setup. Unfortunately I don't think I can fix it in time for 3.0.10, so I've moved this to the 3.0.11 milestone.

@rsim
rsim commented Aug 4, 2011

I just wanted to comment that it is more safe to use activerecord-oracle_enhanced-adapter also on JRuby to access Oracle database - it is tested and is passing all AR tests on Oracle.

activerecord-jdbc-adapter is not tested and not passing all AR tests on Oracle therefore there might be a lot of specific situations where something is not working.

@dchelimsky

So perhaps this really belongs in the activerecord-jdbc-adapter project, no? I'll be glad to close this and reopen there unless you're super excited to fix this @tenderlove.

@tenderlove
Member

@dchelimsky no, I'm really not super excited to fix this! ;-)

Probably the activerecord-jdbc-adapter bug tracker is a better place.

@dchelimsky dchelimsky closed this Aug 4, 2011
@dchelimsky

@rsim - I just tried using the activerecord-oracle_enhanced-adapter instead of the activerecord-jdbc-adapter. It did resolve this particular issue, but it also slowed things down quite a bit. Running specs using the activerecord-jdbc-adapter takes under 15 seconds, but with the activerecord-oracle_enhanced-adapter it took 87 seconds.

@rsim
rsim commented Aug 5, 2011

@dchelimsky oracle_enhanced is written in pure Ruby and jdbc adapter has many things implemented in Java therefore it could be slower in some cases. But if you see such dramatic difference then I would like to have a look on that. Could you please prepare some sample script which demonstrates this huge difference and post it as an issue at https://github.com/rsim/oracle-enhanced/issues ?

@dchelimsky

@rsim be more than happy to, but it won't be until next week some time (gotta be on my work computer and won't have time today).

@dchelimsky

For anyone besides @rsim who may be following along, I discovered some new information and reported it to the oracle-enhanced project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment