webentwicklung-frage-antwort-db.com.de

Kriterien für Ruhezustand Join-Abfrage eins zu viele

Ich habe eine Katzen- und eine Besitzerklasse. Eine Katze hat einen Besitzer, aber ein Besitzer kann viele Katzen haben. Was ich abfragen möchte ist alle Besitzer, die eine Katze mit blauen Augen haben.

class Cat {
    Owner owner; //referenced from Owner.id
    String eyeColor;
}

class Owner {
    List<Cat> catList;
}

Ich habe einige Codes ausprobiert, weiß aber wirklich nicht, was ich tun soll.

Criteria criteria = getCurrentSession().createCriteria(cat.getClass(), "cat");
criteria.createAlias("cat.owner", "owner");    
criteria.add(Restrictions.eq("cat.eyeColor", "blue");
25
hellzone

Kriterien können nur Projektionen oder die Stammentität auswählen. Nicht irgendein verbundenes Unternehmen. Einige Abfragen lassen sich daher nicht mit Kriterien ausdrücken (ein guter Grund mehr, HQL zu verwenden, zusätzlich zu einer viel besseren Lesbarkeit und Prägnanz).

Hier ist jedoch nicht alles verloren, da Ihre Zuordnung bidirektional ist. Sie benötigen also nur das Äquivalent der HQL-Abfrage

select distinct owner from Owner owner 
join owner.cats cat 
where cat.eyeColor = 'blue'

Welches ist

Criteria c = session.createCriteria(Owner.class, "owner");
c.createAlias("owner.cats", "cat");
c.add(Restrictions.eq("cat.eyeColor", "blue");
c.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
43
JB Nizet

Versuche dies:

DetachedCriteria dc = DetachedCriteria.forClass(Cat.class, "inner")
    .add(Restrictions.eq("eyeColor", "blue"))
    .add(Restrictions.eqProperty("inner.owner", "outer.id"));

session.createCriteria(Owner.class, "outer")
    .add(Subqueries.exists(dc))
    .list();

Dies kann den Index in der Datenbank verwenden und führt keine speicherinterne distinct -Operation wie in der Version von @JB Nizet aus (siehe meinen Kommentar dort). Der Index wird sein:

CREATE INDEX idx_cat_owner_eyecolor ON Cat(fkOwner, eyeColor)

Stellen Sie sich die distinct -Operation (entweder in SQL oder im Speicher) als einen Codegeruch vor. Es wird selten verwendet und wird von vielen unerfahrenen Programmierern verwendet, um das Problem zu beheben. "Warum habe ich diese Zeile zweimal?" Es kann fast immer wie in diesem Fall umgeschrieben werden. Es gibt nur wenige Anwendungsfälle, in denen dies erforderlich ist.

4
Oliv