简体   繁体   中英

Objectify: querying for content of foreign keys

I have three entities as Human, Dog, Treat. The Treat entity has the key Key<Dog> , and the Dog entity has the key Key<Human> . When I query for Treat, I want a response that contains the actual Entity for Dog, and the entity for Dog must contain the actual entity for Human: as opposed to just the keys. How do I do that?

update

So I would like to be able to execute the following two queries

  • getAllTreats() should return a list of all treats, where through each treat I can access Dog data and then through said Dog data find Human data.
  • Given a Treat id, I would like to retrieve that Treat with it's Dog data and with the said Dog's Human data.

Code: (I gave pgiecek +1 because he mentioned the @Parent notation. But the problem still remains, at least for the single Treat by treatId)

@Entity
public class Human {
    @Id
    private Long id;
    private String name;
}

@Entity
public class Dog {
    @Id
    private Long id;
    private String name;
    @Load
    @Parent
    private Ref<Human> human;
}


@Entity
public class Treat {
    @Id
    private Long id;
    private String name;
    @Load
    @Parent
    private Ref<Dog> dog;
}

Try to use Ref<?> along with @Load annotation instead of Key<?> . The Ref<?> works just like a Key<?> but allows you to directly access the actual entity object. Furthermore, the @Load annotation enables you to load associated entity objects more efficiently.

Here you can find more details on Ref<?> and on @Load .

Update

Query 1

List<Treat> treats = ofy.load().type(Treat.class).list()

For each Treat object you have to access Dog reference and fetch it manually via Ref<?>.get() method. The same applies for Human . However, you can use @Load annotation for your parent fields.

Query 2

If you have only ID of a Treat , it is not possible to load the entity because the all ancestor path is actually the key of the entity.

The complete key identifying the entity consists of a sequence of kind-identifier pairs specifying its ancestor path and terminating with those of the entity itself.

In your case the Treat's key looks like follows.

Key = [Human:ID, Dog:ID, Treat:ID]

In order to retrieve a concrete Treat instance, you need to know either its ID along with all parents ( Dog and Human instances/IDs in your case) or its key. Look at Key<?>.toWebSafeString() and Key<?>.create(String) (or Key<?>.valueOf(String) ) methods that may help you to serialize the key into String and restore it later.

Treat treat = ... // create a new instance along with its parents

String webSafeKey = Key.create(treat).toWebSafeString();

// do whatever you need

Key<Treat> treatKey = Key.<Treat>create(webSafeKey);

Treat loaded = ofy.load().key(treatKey).now();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM