Skip to content

Retrieving same raw connection not considered identical in terms of Hash#compare_by_identity #8224

@janko

Description

@janko

Environment Information

$ ruby -v
jruby 9.4.6.0 (3.1.4) 2024-02-20 576fab2c51 OpenJDK 64-Bit Server VM 21.0.1 on 21.0.1 +jit [arm64-darwin]
$ uname -a
Darwin janko.local 23.4.0 Darwin Kernel Version 23.4.0: Fri Mar 15 00:12:41 PDT 2024; root:xnu-10063.101.17~1/RELEASE_ARM64_T8103 arm64

I'm using activerecord-jdbc-adapter version 70.2.

Expected Behavior

I expected same raw connection to be considered identical by JRuby when using as hash key with compare_by_identity turned on.

Actual Behavior

require "bundler/inline"

gemfile do
  gem "activerecord", "7.0.8.1"
  gem "activerecord-jdbc-adapter", "70.2"
  gem "jdbc-sqlite3"
end

require "active_record"

ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")

hash = {}
hash.compare_by_identity

hash[ActiveRecord::Base.connection.raw_connection.connection] = "1"
p hash[ActiveRecord::Base.connection.raw_connection.connection]

The above script prints out nil instead of "1", because JRuby considers the connection objects different, even though they have the same #object_id and #hash, and are equal in terms of #==, #eql? and #equal?.

I discovered this while debugging test failures in sequel-activerecord_connection gem, which enables Sequel to reuse Active Record's DB connection. Sequel internally stores transaction state in a hash with compare_by_identity turned on, where hash keys are raw connection objects. Sequel's JDBC adapter itself doesn't appear to have any issues, this only happens if I swap retrieving the connection to go through Active Record.

I could disable compare_by_identity in the sequel-activerecord_connection gem when using JRuby, but I thought I'd report it since I already did the hard work of debugging this issue, and found it surprising that two objects can communicate they're identical but aren't always 😅

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions