livehelpnow / tds_ecto

TDS Adapter for Ecto
57 stars 34 forks source link

Ecto 2 : Ecto.StaleEntryError attempted to insert a stale struct #42

Closed wstucco closed 7 years ago

wstucco commented 7 years ago

When trying to insert a record Ecto returns this error.

** (Ecto.StaleEntryError) attempted to insert a stale struct:

To reproduce the bug


defmodule App.Test do
  use Ecto.Schema

  schema "test" do
    field :f, :string
  end

end
iex(4)> %App.Test{f: "f"} |> App.Repo.insert!
[debug] QUERY OK db=21.7ms
INSERT INTO [test] ([f]) OUTPUT INSERTED.[id] VALUES (@1) ["f"]

** (Ecto.StaleEntryError) attempted to insert a stale struct:

I've debugged the issue a little and found that after calling the query method of the Sql adapter the result has num_rows set to zero.

%Tds.Result{columns: ["id"], command: nil, num_rows: 0, rows: [[1]]}

Anyway, the record is created.

ewitchin commented 7 years ago

There has been a code update within the latest TDS driver that should fix this issue now. Thank you for your patience and reporting this issue!

sardaukar commented 7 years ago

@ewitchin I'm still seeing this on 2.0.0-alpha (locked at 215ef65). My local tds dep is 0.6.0-alpha locked at cc81d97. Do I need to do anything special to update it?

mjaric commented 7 years ago

Did you run migrations or that was some insert statement in some transaction?

sardaukar commented 7 years ago

This is running mix test. No migrations, using an existing MS SQL database.

mjaric commented 7 years ago

Could you describe what was the order and type of queries in last transaction or unit test which failed?

sardaukar commented 7 years ago

I just ran

mix phx.gen.html Content Item somedata analysis:string available:naive_datetime contents:string typecode:integer userid:integer onhold:integer created:naive_datetime available:naive_datetime url:string

and then ran the tests. All the tests fail with the same error:

  1) test update item redirects when data is valid (DemureWeb.ItemControllerTest)
     test/demure_web/controllers/item_controller_test.exs:58
     ** (Ecto.StaleEntryError) attempted to insert a stale struct:

     %Demure.Content.Item{__meta__: #Ecto.Schema.Metadata<:built, "somedata">, analysis: nil, available: nil, contents: nil, created: nil, date: nil, heading: nil, id: nil, onhold: nil, typecode: nil, url: nil, userid: nil}

     stacktrace:
       (ecto) lib/ecto/repo/schema.ex:475: Ecto.Repo.Schema.apply/4
       (ecto) lib/ecto/repo/schema.ex:205: anonymous fn/13 in Ecto.Repo.Schema.do_insert/4
       test/Demure_web/controllers/item_controller_test.exs:11: DemureWeb.ItemControllerTest.fixture/1
       test/Demure_web/controllers/item_controller_test.exs:85: DemureWeb.ItemControllerTest.create_item/1
       test/Demure_web/controllers/item_controller_test.exs:1: DemureWeb.ItemControllerTest.__ex_unit__/2
sardaukar commented 7 years ago

Here's the table structure on the existing MS SQL server:

screen shot 2017-08-18 at 16 22 53

sardaukar commented 7 years ago

@mjaric let me know if you need more info. Unfortunately (I think you might get this a lot on this project) I can't post the source :|

mjaric commented 7 years ago

Dont worry for source code it is just matter to create similar scenario to reproduce issue. I think this has something to do with inserts and the fact that result do not contain rows affected output parameter. But I thought i solved it few weeks ago. So this is when you run migration and it fails to read if shcema_migration row is inserted so it rolls back complete transaction including schema change stuff.

I will check this definetlly. Could you just let me know which erlang, elixir and phoenix version you are using?

sardaukar commented 7 years ago

Erlang 20.0, Elixir 1.5.0, Phoenix 1.3.0 on macOS 10.12.6

mjaric commented 7 years ago

Thanks