2012-01-13 18 views
5

मैं सफलता के बिना एक एसक्यूएल क्वेरी को मानदंड एपीआई में परिवर्तित करने का प्रयास करता हूं। मैं दो अलग-अलग प्रश्न बना सकता हूं जो मुझे आवश्यक मूल्यों को वापस कर सकते हैं, लेकिन मुझे नहीं पता कि उन्हें एक प्रश्न में कैसे जोड़ना है।जेपीए 2 + मानदंड एपीआई - एक सबक्वायरी को परिभाषित करना

select company.*, ticketcount.counter from company 
    join 
(select company, COUNT(*) as counter from ticket where state<16 group by company) ticketcount 
on company.compid = ticketcount.company; 

इस मानदंड क्वेरी रिटर्न भीतरी क्वेरी परिणाम:

CriteriaBuilder cb = em.getCriteriaBuilder(); 
CriteriaQuery<intCompany> qTicket = cb.createQuery(intCompany.class); 
Root<Ticket> from = qTicket.from(Ticket.class); 
Path groupBy = from.get("company");   
Predicate state = cb.notEqual(from.<State>get("state"), getStateById(16));   
qTicket.select(cb.construct(
    intCompany.class, cb.count(from),from.<Company>get("company"))) 
     .where(state).groupBy(groupBy);     
em.createQuery(qTicket).getResultList(); 

आवेदन मैं एक छोटा सा आवरण/सहायक वर्ग में परिभाषित किया गया है:

यहाँ एसक्यूएल बयान जो काम करता है

public class intCompany{ 
    public Company comp; 
    public Long opentickets; 
    public intCompany(Long opentickets,Company comp){ 
     this.comp = comp; 
     this.opentickets = opentickets; 
    } 
    public intCompany(){ 

    } 
} 

तो क्या किसी को यह पता है कि यह काम कैसे प्राप्त करें?

अद्यतन

धन्यवाद। जैसा कि आपने सुझाव दिया है मैंने अपनी मानदंड क्वेरी बदल दी है। मुझे जो जानकारी चाहिए वो प्राप्त करने के लिए मुझे अंत में एक लूप जोड़ना पड़ा।

List<intCompany> result = em.createQuery(cq).getResultList(); 
List<Company> cresult = new ArrayList(); 
    for(intCompany ic: result){ 
     ic.comp.setOpentickets(ic.opentickets.intValue()); 
     cresult.add(ic.comp); 
    } 
return cresult; 

शायद मूल एसक्यूएल को मानदंड एपीआई में परिवर्तित करना संभव नहीं है।

कोई अन्य अपडेट

मैं पता लगा रहा

select company.*, ticketcount.counter from company 
    left join 
(select company, COUNT(*) as counter from ticket where state<16 group by company) ticketcount 
on company.compid = ticketcount.company; 

करने के लिए मूल एसक्यूएल अभिव्यक्ति को बदलने के लिए नहीं तो मैं टिकट तालिका में कोई प्रविष्टियों के साथ कंपनियों के नहीं मिलता था।

तो क्या कोई अन्य सुझाव हैं?

उत्तर

2

आपके पास लगभग सबकुछ किया गया है।

//---// 
CriteriaBuilder cb = em.getCriteriaBuilder(); 
//Your Wrapper class constructor must match with multiselect arguments 
CriteriaQuery<IntCompany> cq = cb.createQuery(IntCompany.class); 
//Main table 
final Root<Ticket> fromTicket= cq.from(Ticket.class); 
//Join defined in Ticket Entity 
final Path company = fromTicket.get("company"); 
//Data to select 
cq.multiselect(cb.count(from), company); 
//Grouping 
cq.groupBy(company); 
//Restrictions (I don't really understand what you're querying) 
Predicate p = cb.lessThan(fromTicket.get("state"), 16); 
//You can add more restrictions 
// p = cb.and/or(p, ...); 
cq.where(p); 
List<IntCompany> results = entityManager.createQuery(cq).getResultList(); 

यह अपेक्षा के अनुसार काम करना चाहिए।

2

मुझे भी इसी तरह की समस्या थी। मेरा समाधान बाएं बाहरी जुड़ने का उपयोग करना था।

CriteriaBuilder cb = entityManager.getCriteriaBuilder(); 
CriteriaQuery<Entity> query = cb.createQuery(Entity.class); 
Root<Entity> root = query.from(Entity.class); 

Join<Entity,ChildEntity> join = root.join(Entity_.children, JoinType.LEFT); 
query.groupBy(root.get(Entity_.id)); 
query.select(
    cb.construct(
    EntityDTO.class, 
    root.get(Entity_.id), 
    root.get(Entity_.name), 
    cb.count(join) 
)); 

यह JoinType.LEFT गारंटी देता है कि आप इकाई रिकॉर्ड (कंपनियों) मिल जाएगा, भले ही वह किसी भी बच्चे संस्थाओं (टिकट) नहीं है।

इकाई वर्ग:

@Entity 
public class Entity { 
    ... 

    @OneToMany(targetEntity = ChildEntity.class, mappedBy = "parent", fetch = FetchType.LAZY, orphanRemoval = false) 
    private Set<ChildEntity> objects; 

    ... 
} 

स्टेटिक मॉडल:

@StaticMetamodel(Entity.class) 
public class Entity_ { 
    public static volatile SingularAttribute<Entity, Long> id; 
    public static volatile SingularAttribute<Entity, String> name; 
    ... 
    public static volatile SetAttribute<Entity, ChildEntity> objects; 
} 
संबंधित मुद्दे