2012-01-26 12 views
10

To kolejne pytanie to:Jak korzystać WZP Criteria API podczas łączenia wielu tabel

How to use JPA Criteria API in JOIN

CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder(); 

CriteriaQuery<Company> criteria = criteriaBuilder.createQuery(Company.class); 
Root<Company> companyRoot = criteria.from(Company.class); 
Join<Company,Product> products = companyRoot.join("dentist"); 
Join<Company, City> cityJoin = companyRoot.join("address.city");//Company->Address->City-city 
criteria.where(criteriaBuilder.equal(products.get("category"), "dentist"),      criteriaBuilder.equal(cityJoin.get("city"),"Leeds")); 

spółka ma swój adres, adres wewnątrz jest City-pojo i Country- Pojo. Jak mogę go użyć w JOIN? Próbowałem odwołać go ze address.city ale mam komunikat o błędzie:

atrybut [address.city] z zarządzanym typu [EntityTypeImpl @ 1692700229: Firma [javaType: Klasa com.test.domain.Company deskryptor: RelationalDescriptor (com.test.domain.Company -> [DatabaseTable (COMPANY)]), odwzorowania: 16]] nie występuje.

Odpowiedz

19

Jeśli użyjesz canonical Metamodel, unikniesz tego rodzaju błędów. W twoim kodzie niewłaściwie użyłeś słowa kluczowego "dentysta", to prawdopodobnie jest przyczyną twojego błędu, ponieważ "dentysta" nie jest polem w encji Firmy.

Jednak patrząc na to, jak zdefiniowano swoją klasę w drugim pytaniu sposobem definiowania że join użyciu Metamodel to:

SetJoin<Company,Product> products = companyRoot.join(Company_.products); 

Jak widać, Metamodel unika się stosowania łańcuchów, a więc unika wielu błędów środowiska wykonawczego. Jeśli mimo to nie używasz metamodel, spróbuj tego:

SetJoin<Company,Product> products = companyRoot.join("products"); 

Jeśli teraz chcesz dodać predicate, czyli coś po where, można napisać coś takiego:

Predicate predicate = criteriaBuilder.equal(products.get(Product_.category), "dentist"); 
criteria.where(predicate); 

Jeśli aby dodać join dla podmiotu miasta:

Join<Company, City> city = companyRoot.join(Company_.city); 
predicate = criteriaBuilder.and(predicate, criteriaBuilder.equal(city.get(City_.cityName), "Leeds"); 
criteria.where(predicate); 

(zakładając, że cityname pole jest poprawna nazwa pola dla miasta).

Powiązane problemy