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)))
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 usingdatascript-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