2016-04-07 10 views
0

Ich habe drei Entitäten als Mensch, Hund, Treat. Die Behandlungseinheit hat den Schlüssel Key<Dog>, und die Dog-Entität hat den Schlüssel Key<Human>. Wenn ich nach Treat frage, möchte ich eine Antwort, die die tatsächliche Entität für Hund enthält, und die Entität für Hund muss die tatsächliche Entität für Mensch enthalten: im Gegensatz zu nur den Schlüsseln. Wie mache ich das?Objectify: Abfrage für Inhalt von Fremdschlüsseln

Update

So würde Ich mag Lage sein, die folgenden beiden Abfragen

  • getAllTreats() sollte ausführen eine Liste aller Leckereien zurück, wo jeder durch behandeln kann ich Dog Daten zugreifen und dann Durch diese Hundedaten finden Sie menschliche Daten.
  • Angesichts einer Behandlung ID, möchte ich, dass behandeln mit seinen Hund Daten und mit den genannten Hund Human-Daten abrufen.

Code: (Ich habe pgiecek +1, weil er die @Parent Notation erwähnt Aber das Problem bleibt, zumindest für die einzelnen Treat von 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; 
} 

Antwort

1

Try Ref<?> verwenden zusammen mit @Load Anmerkung statt Key<?>. Die Ref<?> funktioniert genau wie eine Key<?>, aber ermöglicht Ihnen den direkten Zugriff auf die tatsächliche Entität Objekt. Darüber hinaus ermöglicht die Annotation @Load, dass Sie verknüpfte Entitätsobjekte effizienter laden können.

Hier finden Sie weitere Details zu Ref<?> und @Load.

aktualisieren

Abfrage 1

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

Für jedes Objekt Treat Sie Dog Bezug auf Zugriff haben und holen es über Ref<?>.get() Verfahren manuell. Gleiches gilt für Human. Sie können jedoch @Load Annotation für Ihre übergeordneten Felder verwenden.

Abfrage 2

Wenn Sie nur ID ein Treat haben, ist es nicht möglich, die Einheit zu laden, weil die alle Vorfahren Weg tatsächlich der Schlüssel des Unternehmens ist.

der vollständige Schlüssel der Entität identifizieren, besteht aus einer Folge von Art-Identifizierer Paare ihre Vorfahren Pfad angeben und sich mit denen der Einheit beendet wird.

In Ihrem Fall sieht der Treat-Key wie folgt aus.

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

Um eine konkrete Treat Instanz zu erhalten, müssen Sie zusammen mit allen Eltern (Dog und Human Instanzen/IDs in Ihrem Fall) oder dessen Schlüssel entweder seine ID kennen.Sehen Sie sich die Methoden Key<?>.toWebSafeString() und Key<?>.create(String) (oder Key<?>.valueOf(String)) an, mit denen Sie den Schlüssel in String serialisieren und später wiederherstellen können.

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(); 
+0

+1 für Ihre Antwort. Aber es gibt ein Problem: Die Art und Weise, in der die Vorfahren-Abfrage funktioniert, scheint zu erfordern, dass ich den Vorfahren im Voraus kenne und dann von oben nach unten meine Abfrage (d. H. Vom Stamm zum Blatt) durchführe. Aber was passiert, wenn alles, was ich habe, eine Leckerbissen ist? Wie bekomme ich eine Behandlung, die einen Hund enthält, der wiederum einen Menschen enthält? –

+0

Können Sie Ihre Frage so aktualisieren, dass sie eine exakte Beziehung zwischen Ihren Entitäten enthält? Sie haben Ahnenwege nicht erwähnt. – pgiecek

+0

Ich habe aktualisiert. –

Verwandte Themen