2017-05-08 5 views
1

는 다음과 같은 두 가지 주어진 테이블을 가지고와 하위 쿼리 : 열 objId은 EclipseLink 기준 쿼리 (JPA)

  1. Objects, 열 taxId, taxValidSynonymIdobjTaxonId
  2. Taxa, taxName을 (분류군을 참고 분류군에 대한 복수입니다)

Taxon이 유효하면 ID와 validSynonymId는 동일하고, 그렇지 않으면 유효하지 않습니다. 당신이 '단지'는 taxValidSynonymId

어떻게 내가 모든 Objects을 얻을 수있는 유효한 분류군의 taxId 가득 모든 분류군을 찾을 필요가 분류군의 모든 동의어를 찾으려면 어디 Taxon 자신의 동의어를 포함 주어진 이름 (이?) SQL이의 은

SELECT * 
FROM Objects 
WHERE objTaxonId IN (
    SELECT taxId 
    FROM Taxa 
    WHERE taxName LIKE 'Test Taxon 1' 
     OR taxSynIdTaxon IN(
     SELECT taxId 
     FROM Taxa 
     WHERE taxName LIKE 'Test Taxon 1' 
    ) 
) 

은 내가 분류군과 동의어의 목록을 얻을 안쪽 부분을 해결 할 수 있었다) 몇 줄의 (그리고 분에 이루어집니다. 지금은 ... Subquery

String NAME_LIKE = "Test Taxon 1"; 
EntityManager em = EntityManagerProvider.getEntityManager("TestDB"); // get the EntityManager 
CriteriaBuilder cb = em.getCriteriaBuilder(); 
CriteriaQuery<TaxonImpl> cqObject = cb.createQuery(TaxonImpl.class);// 
Root<TaxonImpl> taxonRoot = cqObject.from(TaxonImpl.class);// 
Expression<String> taxon_name = taxonRoot.<String> get("taxName"); 
Predicate where = cb.equal(taxon_name, NAME_LIKE); 
// subquery 
Subquery<Integer> subQuery = cqObject.subquery(Integer.class); 
Root<TaxonImpl> subRoot = subQuery.from(clsImpl); 
subQuery.select(subRoot.<Integer> get("taxId")); 
subQuery.where(cb.equal(subRoot.<String> get("taxName"), NAME_LIKE)); 
where = cb.or(where, taxonRoot.get("taxValidSynonymId").in(subQuery)); 
cqObject.where(where); 
Query query = em.createQuery(cqObject); 
List<TaxonImpl> result = query.getResultList(); 

참고이 Query을 변환해야합니다 분류군 내 실제 응용 프로그램 코드 (하나 개의 관계 (대상 엔티티가 TaxonImpl입니다)

에 많은으로 매핑된다 하위 쿼리에서) 동적으로 될 것입니다, 그래서 Native Query 나를 도와주지 않습니다.

답변

1

내가 querysubquery을 "변환"하는 방법을 알아 냈다하지만 Eclipselink 내가 TaxonImpl 결과에의 시도 때 두 오류

첫 번째 필드를 통해 액세스를 금지 한 날 던져 (그 첫 번째 시도 내지도에서와 TaxonEntity로 매핑되는 파일이 후 너무

내가 SQL 1 형성하기 위해 노력 :.. 이상한 일 JPA에 하지만 Eclipselink 발생 일 :

SELECT t0.objIdObject, t0.objAdminCreated, t0.objAdminCreator, t0.objAdminEdited, t0.objAdminEditor, t0.objAdminImport1, t0.objAdminImport2, t0.objAddBool1, t0.objAddBool2, t0.objAddBool3, t0.objAddBool4, t0.objAddBool5, t0.objAddDateTime1, t0.objAddDateTime2, t0.objCommonComments, t0.objCommonDescription, t0.objCommonKeywords, t0.objCommonName, t0.objCommonPublished, t0.objCommonPublishedAs, t0.objCommonStatus, t0.objCommonType, t0.objCommonTypustype, t0.objDetAccuracy, t0.objDetCf, t0.objDetComments, t0.objDetDate, t0.objDetMethod, t0.objDetResult, t0.objAddFloat1, t0.objAddFloat2, t0.objAddFloat3, t0.objAddFloat4, t0.objAddFloat5, t0.objEventAbundance, t0.objEventCollectionMethod, t0.objEventComments, t0.objEventMoreContacts, t0.objEventDateDay1, t0.objEventDate1, t0.objEventDateMonth1, t0.objEventDate2, t0.objEventDateUncertain, t0.objEventDateYear1, t0.objEventEcosystem, t0.objEventHabitat, t0.objEventNumber, t0.objEventPermission, t0.objEventSubstratum, t0.objEventTime1, t0.objEventTime2, t0.objEventWeekNumber, t0.objFlora, t0.objGuidObject, t0.objIOComments, t0.objIODeAccessed, t0.objAddInt1, t0.objAddInt2, t0.objAddInt3, t0.objAddInt4, t0.objAddInt5, t0.objStorageForeignNumber, t0.objStorageNumber, t0.objStorageNumberInCollection, t0.objStorageNumberOld, t0.objStorageNumberPrefix, t0.objAddLkp1, t0.objAddLkp10, t0.objAddLkp2, t0.objAddLkp3, t0.objAddLkp4, t0.objAddLkp5, t0.objAddLkp6, t0.objAddLkp7, t0.objAddLkp8, t0.objAddLkp9, t0.objAddLkpCs1, t0.objAddLkpCs10, t0.objAddLkpCs11, t0.objAddLkpCs12, t0.objAddLkpCs13, t0.objAddLkpCs14, t0.objAddLkpCs15, t0.objAddLkpCs2, t0.objAddLkpCs3, t0.objAddLkpCs4, t0.objAddLkpCs5, t0.objAddLkpCs6, t0.objAddLkpCs7, t0.objAddLkpCs8, t0.objAddLkpCs9, t0.objOriginAccessionDate, t0.objOriginAccessionNumber, t0.objOriginComments, t0.objOriginMoreContacts, t0.objOriginSource, t0.objOriginType, t0.objPreparationComments, t0.objPreparationDate, t0.objPreparationType, t0.objPropAdults, t0.objPropAge, t0.objPropAgeUnit, t0.objPropEggs, t0.objPropFemale, t0.objPropHeight, t0.objPropHeightUnit, t0.objPropJuveniles, t0.objPropLarvae, t0.objPropLength, t0.objPropLengthUnit, t0.objPropMale, t0.objPropObservation, t0.objPropObservationComments, t0.objPropPupae, t0.objPropSex, t0.objPropStadium, t0.objPropWeight, t0.objPropWeightUnit, t0.objPropWidth, t0.objPropWidthUnit, t0.objSiteComments, t0.objStorageComments, t0.objStorageContainerNumber, t0.objStorageContainerPieces, t0.objStorageContainerType, t0.objStorageLevel1, t0.objStorageLevel2, t0.objStorageLevel3, t0.objStorageLevel4, t0.objStorageLevel5, t0.objStorageNumberInContainer, t0.objstoragePieces, t0.objStorageValue, t0.objStorageValueUnit, t0.objAddText1, t0.objAddText10, t0.objAddText2, t0.objAddText3, t0.objAddText4, t0.objAddText5, t0.objAddText6, t0.objAddText7, t0.objAddText8, t0.objAddText9, t0.objIdCollection, t0.objCommonIdReference, t0.objDetIdContact, t0.objDetIdReference, t0.objEventIdContact, t0.objIdExcursion, t0.objOriginIdContact, t0.objPreparationIdContact, t0.objIdProject, t0.objSiteIdSite, t0.objdetIdTaxon 
FROM tObjects t0 
WHERE t0.objdetIdTaxon IN (
    SELECT t1.taxIdTaxon.t1.taxIdTaxon 
    FROM tTaxa t1 
    WHERE (t1.taxTaxonDisplay LIKE 'Test Taxon 1' 
     OR t1.taxSynIdTaxon IN (
     SELECT t2.taxSynIdTaxon 
     FROM tTaxa t2 
     WHERE t2.taxTaxonDisplay LIKE 'Test Taxon 1'))) 

오류를 취할 : 전체 쓰레기

SELECT t1.taxIdTaxon.t1.taxIdTaxon 

이다. 당신은 int 타입에서 함수를 실행할 수 없다!

이 오류 (버그?)를 해결하는 것은 (여전히 같은 결과를 반환하는) 새로운 구조를 소개

SELECT t1.objIdObject, t1.objAdminCreated, t1.objAdminCreator, t1.objAdminEdited, t1.objAdminEditor, t1.objAdminImport1, t1.objAdminImport2, t1.objAddBool1, t1.objAddBool2, t1.objAddBool3, t1.objAddBool4, t1.objAddBool5, t1.objAddDateTime1, t1.objAddDateTime2, t1.objCommonComments, t1.objCommonDescription, t1.objCommonKeywords, t1.objCommonName, t1.objCommonPublished, t1.objCommonPublishedAs, t1.objCommonStatus, t1.objCommonType, t1.objCommonTypustype, t1.objDetAccuracy, t1.objDetCf, t1.objDetComments, t1.objDetDate, t1.objDetMethod, t1.objDetResult, t1.objAddFloat1, t1.objAddFloat2, t1.objAddFloat3, t1.objAddFloat4, t1.objAddFloat5, t1.objEventAbundance, t1.objEventCollectionMethod, t1.objEventComments, t1.objEventMoreContacts, t1.objEventDateDay1, t1.objEventDate1, t1.objEventDateMonth1, t1.objEventDate2, t1.objEventDateUncertain, t1.objEventDateYear1, t1.objEventEcosystem, t1.objEventHabitat, t1.objEventNumber, t1.objEventPermission, t1.objEventSubstratum, t1.objEventTime1, t1.objEventTime2, t1.objEventWeekNumber, t1.objFlora, t1.objGuidObject, t1.objIOComments, t1.objIODeAccessed, t1.objAddInt1, t1.objAddInt2, t1.objAddInt3, t1.objAddInt4, t1.objAddInt5, t1.objStorageForeignNumber, t1.objStorageNumber, t1.objStorageNumberInCollection, t1.objStorageNumberOld, t1.objStorageNumberPrefix, t1.objAddLkp1, t1.objAddLkp10, t1.objAddLkp2, t1.objAddLkp3, t1.objAddLkp4, t1.objAddLkp5, t1.objAddLkp6, t1.objAddLkp7, t1.objAddLkp8, t1.objAddLkp9, t1.objAddLkpCs1, t1.objAddLkpCs10, t1.objAddLkpCs11, t1.objAddLkpCs12, t1.objAddLkpCs13, t1.objAddLkpCs14, t1.objAddLkpCs15, t1.objAddLkpCs2, t1.objAddLkpCs3, t1.objAddLkpCs4, t1.objAddLkpCs5, t1.objAddLkpCs6, t1.objAddLkpCs7, t1.objAddLkpCs8, t1.objAddLkpCs9, t1.objOriginAccessionDate, t1.objOriginAccessionNumber, t1.objOriginComments, t1.objOriginMoreContacts, t1.objOriginSource, t1.objOriginType, t1.objPreparationComments, t1.objPreparationDate, t1.objPreparationType, t1.objPropAdults, t1.objPropAge, t1.objPropAgeUnit, t1.objPropEggs, t1.objPropFemale, t1.objPropHeight, t1.objPropHeightUnit, t1.objPropJuveniles, t1.objPropLarvae, t1.objPropLength, t1.objPropLengthUnit, t1.objPropMale, t1.objPropObservation, t1.objPropObservationComments, t1.objPropPupae, t1.objPropSex, t1.objPropStadium, t1.objPropWeight, t1.objPropWeightUnit, t1.objPropWidth, t1.objPropWidthUnit, t1.objSiteComments, t1.objStorageComments, t1.objStorageContainerNumber, t1.objStorageContainerPieces, t1.objStorageContainerType, t1.objStorageLevel1, t1.objStorageLevel2, t1.objStorageLevel3, t1.objStorageLevel4, t1.objStorageLevel5, t1.objStorageNumberInContainer, t1.objstoragePieces, t1.objStorageValue, t1.objStorageValueUnit, t1.objAddText1, t1.objAddText10, t1.objAddText2, t1.objAddText3, t1.objAddText4, t1.objAddText5, t1.objAddText6, t1.objAddText7, t1.objAddText8, t1.objAddText9, t1.objIdCollection, t1.objCommonIdReference, t1.objDetIdContact, t1.objDetIdReference, t1.objEventIdContact, t1.objIdExcursion, t1.objOriginIdContact, t1.objPreparationIdContact, t1.objIdProject, t1.objSiteIdSite, t1.objdetIdTaxon 
FROM tTaxa t0, tObjects t1 
WHERE (
    t0.taxIdTaxon IN (
     SELECT t2.taxIdTaxon 
     FROM tTaxa t2 
     WHERE (t2.taxTaxonDisplay LIKE 'Test Taxon 1' 
      OR t2.taxSynIdTaxon IN (
      SELECT t3.taxSynIdTaxon 
      FROM tTaxa t3 
      WHERE t3.taxTaxonDisplay LIKE 'Test Taxon 1' 
      ) 
     ) 
    ) AND (t0.taxIdTaxon = t1.objdetIdTaxon) 
) 

이 나에게 이상한 것 같다,하지만이 작동 - 그리고 내 다른 쿼리보다 빠른, 여기에는 inner join

참고 : Eclipselink는 JoinType을 무시합니다. 당신이 뭘 통과하든간에 left outer join 걸립니다. (문서가 다른 것을 말합니다!)

마침내 난 joinjoinless

private static Predicate addSynonymsWithJoins(Root<BioObjectImpl> r, CriteriaBuilder b, CriteriaQuery cq, 
     Attribute attr, Path path, Object value) { 
    Join taxJoin = r.join(BioObjectEnum.taxon.name(), JoinType.INNER); 

    Path<Object> taxValidSynonymId = taxJoin.get(TaxonEnum.validSynonymId.name()); 
    Subquery<TaxonImpl> innerSubquery = cq.subquery(TaxonImpl.class); 
    Root fromSubTax = innerSubquery.from(TaxonImpl.class); 
    innerSubquery.select(fromSubTax.<Integer> get(TaxonEnum.id.name())); 
    Predicate dynamic1 = cb.like(fromSubTax.get(TaxonEnum.name.name()), 
    NAME_LIKE); 
    innerSubquery.where(dynamic1); 
    Predicate dynamic2 = resolveComparator(b, attr, taxJoin.get(attr.getPropertyName()), attr.getValue());// 
    Predicate p = b.or(taxValidSynonymId.in(innerSubquery), dynamic2); 

    return p; 
} 

private static Predicate addSynonymsWithoutJoins(Root<BioObjectImpl> r, CriteriaBuilder b, CriteriaQuery cq, 
     Attribute attr, Path path, Object value) { 
    cq.select(r); 

    Path<Integer> objTaxonId = r.<Integer> get(BioObjectEnum.taxon.name()).get(TaxonEnum.id.name()); 

    Subquery<Integer> t2 = cq.subquery(Integer.class); 
    Root<TaxonImpl> t2fromTaxon = t2.from(TaxonImpl.class); 
    Path<Integer> t2taxId = t2fromTaxon.<Integer> get(TaxonEnum.validSynonymId.name()); 
    t2.select(t2taxId); 
    Predicate t2dynamicWhere = resolveComparator(b, attr, t2fromTaxon.get(attr.getPropertyName()), attr.getValue()); 
    t2.where(t2dynamicWhere); 

    Subquery<Integer> t1 = cq.subquery(Integer.class); 
    Root<TaxonImpl> t1fromTaxon = t1.from(TaxonImpl.class); 
    Predicate t1dynamicWhere = b.like(fromSubTax.get(TaxonEnum.name.name()), 
    NAME_LIKE); 
    Path<Integer> t1Select = t1fromTaxon.<Integer> get(TaxonEnum.id.name()); 

    t1.select(t1Select); 
    Path<Integer> t1TaxSynonymId = t1fromTaxon.<Integer> get(TaxonEnum.validSynonymId.name()); 
    t1dynamicWhere = b.or(t1dynamicWhere, t1TaxSynonymId.in(t2)); 
    t1.where(t1dynamicWhere); 

    Predicate where = objTaxonId.in(t1); 
    return where; 
} 
대한 두 가지 예를 제공한다