Fork me on GitHub
#datomic
<
2020-05-24
>
yokoyama.km19:05:16

Hello, I'm trying to use lookup refs in a transaction, but I'm having trouble. I have the following tx-data in which I try to add a new fact: the user identified by follower-id now follows the user identified by followed-id (it is a Twitter-clone app):

{:db/id       [:user/id follower-uuid]
 :user/follow [:user/id followed-uuid]}
The schema is already in place and :user/id is unique. I'm receiving this error message from Datomic:
#object[datomic.promise$settable_future$reify__4751
        0x3be40c44
        {:status :failed,
         :val #error{:cause ":db.error/not-an-entity Unable to resolve entity: 956eb63e-6f30-4e94-a378-eee8ae0156cd in datom [[:user/id #uuid \"37b70f39-70cd-473d-9959-f81502621302\"] :user/follow #uuid \"956eb63e-6f30-4e94-a378-eee8ae0156cd\"]",
                     :data {:entity #uuid"956eb63e-6f30-4e94-a378-eee8ae0156cd",
                            :datom [[:user/id #uuid"37b70f39-70cd-473d-9959-f81502621302"]
                                    :user/follow
                                    #uuid"956eb63e-6f30-4e94-a378-eee8ae0156cd"],
                            :db/error :db.error/not-an-entity},
[more omitted]
The schema for :user/id and :user/follow are the following:
{:db/ident       :user/id
 :db/valueType   :db.type/uuid
 :db/cardinality :db.cardinality/one
 :db/unique      :db.unique/identity
 :db/index       true}

{:db/ident       :user/follow
 :db/valueType   :db.type/ref
 :db/cardinality :db.cardinality/many}
Does anyone have a clue? Thank you

lanejo0120:05:14

Hi @ , do both of the users exist in the database?

yokoyama.km20:05:08

Yes, they do. I can correctly retrieve them.

yokoyama.km20:05:13

And if I replace [:user/id followed-uuid] with the entity id of the followed user, it works as expected.

lanejo0120:05:19

And what if your tx data was instead

{:user/id follower-uuid
 :user/follow [:user/id followed-uuid]}

yokoyama.km20:05:23

I haven't tried that. I'll try it and comment here

yokoyama.km20:05:11

The rationale would be: since :user/id is unique, your suggestion would upsert the :user/follow attribute?

lanejo0120:05:59

Yep, and it will also upsert the follower user as well, without the need for db/id (unless you need a tempid for something, but it doesn't look like this example does.)

lanejo0120:05:46

Which datomic is this? Datomic cloud, free, pro/on-prem?

simon21:05:18

Are you sure u're using the uuid fully and correctly? Could you post the full transaction with the value of the follower-uuid ?

yokoyama.km21:05:25

I'm using the datomic-free API, but this example is running with an in-memory database ("datomic:<mem://mydb|mem://mydb>")

lanejo0121:05:17

Ok, did the above work?

yokoyama.km21:05:13

Sorry, I was away from my laptop, @. It didn't work. It returns the same error as before.

yokoyama.km21:05:28

@, yes, it looks ok:

(d/transact conn [#:user{:id #uuid "956eb63e-6f30-4e94-a378-eee8ae0156cd", :follow [:user/id #uuid "37b70f39-70cd-473d-9959-f81502621302"]}])

yokoyama.km21:05:03

I have other data that look similar and work. For instance:

#:like{:id           uuid
       :created-at   created-at
       :user         [:user/id user-uuid]
       :source-tweet [:tweet/id source-tweet-uuid]}

simon21:05:53

For the follow, I think it should be ... :follow [[:user/id ...]] 'cos ref type-> many card.., or use a set #{[:user/id ...]}

yokoyama.km22:05:36

Wow, that worked! Will Datomic create a new datom of the form [follower-entity-id :user/follow new-followed-entity-id] for each successive transaction? For instance, when first user (entity id 1) follows second user (entity id 2) it creates datom [1 :user/follow 2 tx-1 true] and then when first user also follows third user (entity id 3), then the following occurs: [1 :user/follow 2 tx-2 false] [1 :user/follow 3 tx-2 true] ? Obviously this wouldn't be the correct result.

yokoyama.km22:05:13

Ok, your screenshot answers that. Thank you, @ and @!