:db.unique/identity does not work for tuple attributes

Hi guys.
The same entity is not transacted second time if it has a composite tuple key.

(d/transact conn [{:db/ident :user/firstName
                   :db/valueType :db.type/string
                   :db/cardinality :db.cardinality/one}
                  {:db/ident :user/lastName
                   :db/valueType :db.type/string
                   :db/cardinality :db.cardinality/one}
                  {:db/ident :user/fullName
                   :db/valueType :db.type/tuple
                   :db/tupleAttrs [:user/firstName :user/lastName]
                   :db/cardinality :db.cardinality/one
                   :db/unique :db.unique/identity}])

(d/transact conn [{:user/firstName "First"
                   :user/lastName "Last"}])

; fails
(d/transact conn [{:user/firstName "First"
                   :user/lastName "Last"}])

Error:

Unique conflict: :user/fullName, value: [\"First\" \"Last\"] already
held by: 17592186045418 asserted for: 17592186045420"

My expectation was that Datomic would perform an upsert as it does with any other value type.

At the same time it is possible to do an upsert if tuple attribute value is specified explicitly:

; works
(d/transact conn [{:user/firstName "First"
                   :user/lastName "Last"
                   :user/fullName ["First", "Last"]}])

UPDATE: This is a duplicate of 1075

2 Likes

Yes, @apopelo, this is correct. If you want upsert you must specify the unique key. You can alway use the actual entity id, in that case, you would not need to use any identity to perform an update. If you do want to identify an entity by a unique key, you must indeed specify that unique key (not its constituents). This is clean and unambiguous. We are looking at updating our docs to make this clear.

1 Like