Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inaccurate temporary IDs after transit deserialization #463

Closed
samcf opened this issue Apr 17, 2024 · 0 comments
Closed

Inaccurate temporary IDs after transit deserialization #463

samcf opened this issue Apr 17, 2024 · 0 comments

Comments

@samcf
Copy link

samcf commented Apr 17, 2024

Ran into an issue when I was mistakenly using empty maps as values for attributes with a :db/valueType of :db.type/ref. When the database is serialized and deserialized using datascript-transit, creating a new entity with a temporary ID of -1 ends up resolving to an ID that already "exists" in the database.

I'm not sure which symptom is more foundational: allowing a reference to an entity with no attributes or that the temporary ID resolved to an ID which was being used as a reference.

I'm also not sure that deserialization is necessary to reproduce, but I couldn't find another way to do it: all other methods resolve -1 to the expected new unique ID.

Code to reproduce

(let [;; create a new database.
      init (ds/empty-db {:mother {:db/valueType :db.type/ref}})
      data (ds/db-with init [[:db/add 1 :name "Sam"]])
      conn (ds/conn-from-db data)

      ;; this creates a new entity and relates it to 1's :mother.
      ;; i don't think this part is a bug, but using empty maps
      ;; to implicitly create new entities is not very useful,
      ;; particularly because you can't have entities with no
      ;; attributes afaik.
      _    (ds/transact! conn [{:db/id 1 :mother {}}])

      ;; this is at least one way to run into this issue:
      ;; serializing and deserializing the database causes the newly
      ;; added entity to re-use an entity id, despite using temp -1.
      seri (dt/write-transit-str @conn)
      conn (ds/conn-from-db (dt/read-transit-str seri))
      _    (ds/transact! conn [{:db/id -1 :name "John"}])]

  ;; inspecting the datoms we can see that the entity "John"
  ;; is using the same :db/id as our empty map entity. "John"
  ;; shouldn't be my mother's name! Expected "John" to have
  ;; a :db/id of 3, not 2.
  (prn (ds/datoms @conn :eavt)))
@tonsky tonsky closed this as completed in a8d8155 Apr 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant