Identity maps across repositories

36 views
Skip to first unread message

Andy Shipman

unread,
Jun 24, 2009, 2:43:34 PM6/24/09
to DataMapper
I need some help understanding how identity maps work across
repositories. I have a spec written (below) to review how object_ids
work across 2 repositories, the :default repository and a second that
points to the same database but called :reloaded.

Using a 1:1 relationship, the object_id of the association is the same
in both repositories, but I would expect it to be different as I
expected there to be 2 identity maps - one for each repository. Is
this not the case? If not, why not?

I've also posted a gist - http://gist.github.com/135434 - that shows
that this is the case across 1:1, 1:n and 1:n using a join table. As
its consistent across these 3 types of associations, I'm obviously
missing something fundamental. Can someone please enlighten me?

(note the code can be run against 0.9.11 and 0.10RC1 but defaults to
0.10RC1)

The code:

require 'rubygems'

# USE_DM_0_9 = true

if defined?(USE_DM_0_9)
DM_GEMS_VERSION = "0.9.11"
DO_GEMS_VERSION = "0.9.12"

gem "data_objects", DO_GEMS_VERSION
gem "do_sqlite3", DO_GEMS_VERSION
gem "dm-core", DM_GEMS_VERSION
end

require 'dm-core'
require 'spec'

SQLITE_FILE = File.join(`pwd`.chomp, "test.db")

DataMapper.setup(:default, "sqlite3:#{SQLITE_FILE}")
DataMapper.setup(:reloaded, "sqlite3:#{SQLITE_FILE}")

class Spouse
include DataMapper::Resource
property :id, Serial
belongs_to :parent
end

class Parent
include DataMapper::Resource
property :id, Serial
has 1, :spouse
end

Spec::Runner.configure do |config|
config.before(:each) do
Spouse.auto_migrate!
Parent.auto_migrate!
end

config.before(:each) do
DataMapper::Repository.context << repository(:default)
end

config.after(:each) do
DataMapper::Repository.context.pop
end
end

describe Parent, "with a spouse, 1 to 1" do
before(:each) do
@parent = Parent.new
@parent.spouse = Spouse.new
@parent.save
@parent.spouse.should_not be_nil
end

it "1 to 1 associations appears to be sharing associations across an
identity map" do
other_spouse_object_id =
repository(:reloaded) do
parent_reloaded = Parent.get(@parent.id)
parent_reloaded.spouse.object_id
end

@parent.spouse.object_id.should_not == other_spouse_object_id
end
end

Ashley Moran

unread,
Jun 25, 2009, 3:29:53 PM6/25/09
to DataMapper
On Jun 24, 7:43 pm, Andy Shipman <a...@cllearview.com> wrote:
> >   it "1 to 1 associations appears to be sharing associations across an
> identity map" do
>     other_spouse_object_id =
>       repository(:reloaded) do
>         parent_reloaded = Parent.get(@parent.id)
>         parent_reloaded.spouse.object_id
>       end
>
>     @parent.spouse.object_id.should_not == other_spouse_object_id
>   end
> end

I consider this behaviour a bug - it appears to contradict the
intention of an Identity Map. It is also inconsistent - the parent
resource gets a unique object, but the children are shared with the
previous identity map.

There is a workaround:

def with_db_reconnect(&blk)
original_repository = DataMapper::Repository.context.pop
repository(:reloaded, &blk)
DataMapper::Repository.context << original_repository
end

it "can be fixed by popping the current repository off the context
stack" do
other_spouse_object_id =
with_db_reconnect do
parent_reloaded = Parent.get(@parent.id)
parent_reloaded.spouse.object_id
end

@parent.spouse.object_id.should_not == other_spouse_object_id
end

Can anyone confirm that the original behaviour is indeed a bug? If
so, I'll file a ticket.

Thanks
Ashley

Dan Kubb (dkubb)

unread,
Jun 26, 2009, 1:48:20 AM6/26/09
to DataMapper
Hi Ashley,

> Can anyone confirm that the original behaviour is indeed a bug?  If
> so, I'll file a ticket.

I can confirm this is a bug.

I intended to introduce the concept of absolute and relative
relationships in the 0.10 series. Absolute means that you explicitly
set the target repository to use at the other end of the
relationship. Relative means that the target repository is based on
the current resource (the source). By default, if you don't specify a
target repository a relationship will be relative.

I think the fix should be relatively simple though, but please create
a ticket to ensure it doesn't get lost in the shuffle.

Dan
(dkubb)

Ashley Moran

unread,
Jun 29, 2009, 4:20:56 PM6/29/09
to datam...@googlegroups.com

On 26 Jun 2009, at 06:48, Dan Kubb (dkubb) wrote:

> I think the fix should be relatively simple though, but please create
> a ticket to ensure it doesn't get lost in the shuffle.

Ticket created[1]. Thanks for looking into it!

Cheers
Ashley

[1] http://datamapper.lighthouseapp.com/projects/20609-datamapper/tickets/931-associations-use-wrong-identity-map-when-one-is-already-on-the-context-stack

--
http://www.patchspace.co.uk/
http://www.linkedin.com/in/ashleymoran
http://aviewfromafar.net/
http://twitter.com/ashleymoran


Reply all
Reply to author
Forward
0 new messages