2016-10-21 2 views
1

Ich muss alle Produkte finden, die kein bestimmtes Allergen mit Hibernate enthalten.Suchen Hibernate-Objekte ohne viele zu viele Beziehung

Hier ist die SQL verwendet, um die Datenbanktabellen zu erstellen:

CREATE TABLE ALLERGEN (id integer IDENTITY PRIMARY KEY, name varchar(20), UNIQUE (id), UNIQUE(name)); 
CREATE TABLE PRODUCT (id integer IDENTITY PRIMARY KEY, name varchar(20), UNIQUE (id), UNIQUE(name)); 
CREATE TABLE PRODUCT_ALLERGEN (product_id integer, allergen_id integer, UNIQUE (product_id, allergen_id), FOREIGN KEY (product_id) REFERENCES PRODUCT (id), FOREIGN KEY (allergen_id) REFERENCES ALLERGEN (id)); 

Hier sind die Hibernate Java-Klassen kommentierte: erscheint

@Entity 
@Table(name = "ALLERGEN") 
class Allergen { 

    @Id 
    @Column(unique = true, nullable = false) 
    @GeneratedValue 
    private Integer id; 
    private String name; 

    // ... 
} 

@Entity 
@Table(name = "PRODUCT") 
public class Product { 

    @Id 
    @Column(unique = true, nullable = false) 
    @GeneratedValue 
    private Integer id; 
    private String name; 
    @ManyToMany(fetch = FetchType.EAGER) 
    @JoinTable(inverseJoinColumns = {@JoinColumn(name = "allergen_id")}) 
    private final Set<Allergen> allergens = new HashSet<>(); 

    // ... 
} 

Diese SQL mir das Ergebnis zu geben, ich will, aber ich sehe nicht, wie man es mithilfe von Hibernate-Kriterien darstellt.

SELECT * FROM PRODUCT WHERE (SELECT COUNT(*) FROM PRODUCT_ALLERGEN WHERE product_id = PRODUCT.id AND allergen_id = 0) = 0; 
+0

Möchten Sie die Abfrage in HQL oder mithilfe der Kriterien-API? –

+0

Ich suchte nach der Lösung in Criteria API, aber ein Äquivalent in HQL wäre auch von Interesse. –

+0

https://www.mkyong.com/hibernate/hibernate-query-example-hql/ – Mahi

Antwort

1

den Kriterien API sollten Sie alle Artikel ohne Allergens durch einen linken Schaffung kommen von Produkt allergen und prüfen, ob es null erhalten können:

final CriteriaBuilder builder = entityManager.getCriteriaBuilder(); 
final CriteriaQuery<Product> c = builder.createQuery(Product.class); 
final Root<Product> root = c.from(Product.class); 
Join<Product, Allergen> allergenJoin = root.join("allergens", JoinType.LEFT); 
c.where(builder.isNull(allergenJoin)); 
c.select(root); 
List<Product> = entityManager.createQuery(c).getResultList(); 

Hinweis: habe ich nicht Geben Sie an, woher Sie den EntityManager erhalten. Normalerweise benutze ich dafür Injektionen, aber es gibt andere Methoden wie die Verwendung einer Fabrik.

+0

erkannte, dass diese Antwort korrekt ist, aber dass meine Frage mehrdeutig war. Ich meinte "finde die Produkte, die kein spezifisches Allergen enthalten." nicht "Produkte finden, die keine Allergene enthalten". –

0

Dieser Code verwendet JPQL, um die Produkte ohne ein spezifisches Allergen zu erhalten.

List<Product> results = manager.createQuery(
     "SELECT p from Product AS p WHERE (SELECT COUNT(a) FROM p.allergens a WHERE a.name = :an) = 0", 
     Product.class) 
    .setParameter("an", "nuts") 
    .getResultList();