का उपयोग करते हुए खंड मैं क्लियर डीएसएल का उपयोग करने के लिए एक पॉलीमोर्फिक के साथ एक प्रश्न लिखने की कोशिश कर रहा हूं जहां खंड।पॉलिमॉर्फिक जहां क्वार्टर डीएस
चूंकि मैं सारणी में क्या करना चाहता हूं, यह समझाने में थोड़ा मुश्किल है, मैं cloned the spring-boot-sample-data-jpa project और इसे जो करने की कोशिश कर रहा हूं उसका एक उदाहरण दिखाने के लिए संशोधित किया गया है।
मैं these model classes, तुम कहाँ ध्यान दें जाएगा कि SpaHotel
और SportHotel
Hotel
इकाई का विस्तार किया है।
मैं एक प्रश्न लिखने की कोशिश कर रहा हूं जो SpaHotel
, या SportHotel
युक्त सभी शहरों को लौटाता है जिसका मुख्य खेल दिए गए प्रकार का है।
मैं एक JPQL version of that query है, जो एक छोटे से बदसूरत है लिखा था (मैं sport is null
हिस्सा दर्शाता है कि यह एक स्पा होटल है पसंद नहीं है), लेकिन मैं क्या चाहते हैं वापस जाने के लिए लगता है।
लेकिन the QueryDsl version of that query काम करने के लिए प्रतीत नहीं होता:
public List<City> findAllCitiesWithSpaOrSportHotelQueryDsl(SportType sportType) {
QCity city = QCity.city;
QHotel hotel = QHotel.hotel;
return queryFactory.from(city)
.join(city.hotels, hotel)
.where(
hotel.instanceOf(SpaHotel.class).or(
hotel.as(QSportHotel.class).mainSport.type.eq(sportType)
)
).list(city);
}
मेरे test के साथ विफल:
test_findAllCitiesWithSpaOrSportHotelQueryDsl(sample.data.jpa.service.CityRepositoryIntegrationTests) Time elapsed: 0.082 sec <<< FAILURE!
java.lang.AssertionError:
Expected: iterable over [<Montreal,Canada>, <Aspen,United States>, <'Neuchatel','Switzerland'>] in any order
but: No item matches: <Montreal,Canada> in [<Aspen,United States>, <'Neuchatel','Switzerland'>]
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:8)
at sample.data.jpa.service.CityRepositoryIntegrationTests.test_findAllCitiesWithSpaOrSportHotelQueryDsl(CityRepositoryIntegrationTests.java:95)
यह मेरी क्वेरी की तरह लगता है वापस नहीं करता है "मॉन्ट्रियल" है, जो वापस आ जाना चाहिए, चूंकि इसमें स्पाहोटल है।
इसके अलावा, मुझे आश्चर्य है कि अगर यह सामान्य है कि QueryDsl एक क्रॉस में मेरी क्वेरी का अनुवाद होगा शामिल हो:
select city0_.id as id1_0_, city0_.country as country2_0_, city0_.name as name3_0_
from city city0_
inner join hotel hotels1_
on city0_.id=hotels1_.city_id
cross join sport sport2_
where hotels1_.main_sport_id=sport2_.id and (hotels1_.type=? or sport2_.type=?)
मेरे सवालों का:
- वापस नहीं "मॉन्ट्रियल" है, जो होता है, जो क्वेरी क्यों है SpaHotel?
- क्या यह प्रश्न लिखने का कोई बेहतर तरीका है?
- क्या यह सामान्य है कि उत्पन्न SQL एक क्रॉस-जॉइन करता है? क्या हम जेपीक्यूएल में जैसे बाएं-जॉइन नहीं कर सकते हैं?
बहुत रोचक, मुझे एहसास नहीं हुआ कि आप एक उप प्रकार के पथ को कास्ट करने के लिए 'leftJoin()' में 'as()' का उपयोग कर सकते हैं। यह मेरी समस्या पूरी तरह से हल करता है। तेज़ उत्तर के लिए और QueryDsl के विकास के लिए बहुत बहुत धन्यवाद। यह विस्मयकारी है। –