2017-02-14 3 views
10

मैं निम्नलिखित देशी SQL क्वेरी है कि मैं जेपीए मापदंड में बदलने की कोशिश कर रहा हूँ है:रूपांतरण जेपीए मानदंड करने के लिए क्वेरी शामिल हों

select et.* from t_empl_tx et, t_dept d 
where et.assigned_dept = d.dept (+) 
    and et.employee_id = :employee_id 
    and (et.start_date >= d.dept_est_date and 
     et.start_date <= d.dept_close_date or 
     et.start_date is null or 
     d.dept is null) 

(कि नोट (+) मोटे तौर पर एक बाईं बाहरी के बराबर है इस मामले में शामिल हों। हाँ, मुझे पता है कि यह वैकल्पिक तालिका, आदि इत्यादि को दर्शाता है)।

EntityManager entityManager = getEntityManager(); 
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); 
CriteriaQuery<EmployeeTransaction> criteriaQuery = criteriaBuilder.createQuery(EmployeeTransaction.class); 
Root<EmployeeTransaction> root = criteriaQuery.from(EmployeeTransaction.class); 

    // this line bombs! 
Join<EmployeeTransaction, Department> join = 
    root.join(EmployeeTransaction_.assignedDepartment).join(Department_.id).join(DepartmentCompositeId_.department, JoinType.LEFT); 

List<Predicate> predicates = new ArrayList<>(); 

predicates.add(criteriaBuilder.equal(root.get(EmployeeTransaction_.id).get(EmployeeTransactionCompositeId_.employeeId), employeeId)); 
predicates.add(criteriaBuilder.or(
    criteriaBuilder.and(
    criteriaBuilder.greaterThanOrEqualTo(root.<Date>get(EmployeeTransaction_.requestedStartDate), join.get(Department_.id).<Date>get(DepartmentCompositeId_.departmentCreationDate)), 
    criteriaBuilder.lessThanOrEqualTo(root.<Date>get(EmployeeTransaction_.requestedStartDate), join.<Date>get(Department_.departmentCloseDate)) 
    ), 
    criteriaBuilder.isNull(root.get(EmployeeTransaction_.requestedStartDate)), 
    criteriaBuilder.isNull(join.get(Department_.id).get(DepartmentCompositeId_.departmentCreationDate)) 
)); 

criteriaQuery.select(root).where(predicates.toArray(new Predicate[]{})); 

TypedQuery<EmployeeTransaction> query = entityManager.createQuery(criteriaQuery); 
List<EmployeeTransaction> result = query.getResultList(); 

यह समस्या है कि मैं एक समग्र आईडी एक भी क्षेत्र के लिए एक स्ट्रिंग स्तंभ, assigedDepartment, शामिल होने के लिए कोशिश कर रहा हूँ लगता है:

यहाँ कोड पर मेरे प्रयास है। यह एसक्यूएल में पूरी तरह से कानूनी है, लेकिन कोड में इतना आसान नहीं है।

एक विकल्प कई उपक्विरी में परिवर्तित करना है, जो बाएं बाहरी के बिंदु को पूरी तरह से मारने लगता है।

क्या कोई यह बता सकता है कि मैं क्या गलत कर रहा हूं?

जेसन

+0

कोई समय एक जवाब लिखने के लिए लेकिन " इकाई 1 से इकाई 1 का चयन करें इकाई 1 .field2 में शामिल हों ... "। यदि आप चाहते हैं कि बाएं उत्सुकता से शामिल हों, तो आपको "फ़ेच में शामिल होने" की आवश्यकता है। –

+0

जॉइनटाइप विशेषता में केवल तीन संभावित मान हैं: INNER, बाएं और दाएं। बाएं शामिल होने के लिए एक विकल्प प्रतीत नहीं होता है। इसके अलावा, जॉइन() लाइन में कुछ गड़बड़ है। भले ही शामिल हों() एक सिंगुलरएट्रिब्यूट लौटाता है <>, मैं इस तरह के आदेशों को चेन नहीं कर सकता। – Jason

+1

जेपीए मानदंड क्वेरी में आप एक तालिका 'विभाग कॉम्पोजिट आईडी' का संदर्भ दे रहे हैं जो SQL क्वेरी में मौजूद नहीं है। कृपया प्रत्येक इकाई – perissf

उत्तर

2

आप अपने संस्थाओं पोस्ट ताकि जवाब अधिक विशिष्ट हो सकता है चाहिए।

हालांकि, मैं कोशिश करूंगा।

select et.* 
from t_empl_tx et 
    left join t_dept d on et.assigned_dept = d.dept 
where 
    et.employee_id = :employee_id 
    and (
     et.start_date >= d.dept_est_date 
     and et.start_date <= d.dept_close_date 
     or et.start_date is null 
     or d.dept is null) 

तो, कुछ ही देर में, आप JoinType.LEFTassignedDepartment को स्थानांतरित करने के लिए है में शामिल होने:

अगर मैं सही हूँ, आप क्वेरी पुनर्लेखन कर सकते हैं

EntityManager entityManager = getEntityManager(); 
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); 
CriteriaQuery<EmployeeTransaction> criteriaQuery = criteriaBuilder.createQuery(EmployeeTransaction.class); 

Root<EmployeeTransaction> root = criteriaQuery.from(EmployeeTransaction.class); 
Join<EmployeeTransaction, Department> department = root.join(EmployeeTransaction_.assignedDepartment, JoinType.LEFT); 
Path<Date> employeeTransactionRequestedStartDate = root.get(EmployeeTransaction_.requestedStartDate); 
Path<DepartmentCompositeId> departmentId = department.get(Department_.id); 
Path<Date> departmentCreationDate = departmentId.get(DepartmentCompositeId_.departmentCreationDate) 
Path<Date> departmentCloseDate = departmentId.get(DepartmentCompositeId_.departmentCloseDate) 

criteriaQuery.select(root).where(
    criteriaBuilder.equal(root.get(EmployeeTransaction_.id).get(EmployeeTransactionCompositeId_.employeeId), employeeId), 
    criteriaBuilder.or(
     criteriaBuilder.and(
      criteriaBuilder.greaterThanOrEqualTo(employeeTransactionRequestedStartDate, departmentCreationDate)), 
      criteriaBuilder.lessThanOrEqualTo(employeeTransactionRequestedStartDate, departmentCloseDate) 
     ), 
     criteriaBuilder.isNull(employeeTransactionRequestedStartDate), 
     criteriaBuilder.isNull(departmentCreationDate) 
    ) 
); 

TypedQuery<EmployeeTransaction> query = entityManager.createQuery(criteriaQuery); 
List<EmployeeTransaction> result = query.getResultList(); 
संबंधित मुद्दे