2017-03-02 1 views
3

내 견본은 표본 (SpecimenImpl)이 null인지 여부, 분류 이름 (WACensusImpl)이 null인지 여부에 관계없이 모든 이미지 (WAHImage) 개체를 검색하고 가능한 경우 견본 이름 또는 분류 이름으로 결과를 표시하고 널 표본 및 null 분류 이름이있는 이미지 객체를 먼저 표시합니다.QueryDSL에서 nullable 하위 개체의 속성을 기준으로 모델 개체를 주문하십시오.

아래 코드를 사용하면 No property coalesce(wAHimage found for type WAHImage 오류가 발생합니다.

내 사용 사례가 not (yet) fully supported in QueryDSL입니다. 즉, 엔터티를 쿼리하고 nullable 하위 개체의 속성에 따라 결과 개체를 정렬하는 기능입니다. 이는 QueryDSL이 LEFT JOIN이 아닌 CROSS JOIN을 사용하고 CROSS JOIN을 사용하여 하위 오브젝트 특성으로 주. 할 수 없기 때.입니다. 이것은 나의 좌절감의 원천 인 것 같아서, 나는 이제 QueryDSL을 고수하기보다는 다른 해결책을 찾고있다.

@Service 
public class ImageService { 
    private ImageRepository imageRepository; 
    public Page<WAHImage> get(Pageable pageable) { 
     return imageRepository.findAllByIsDeleted(false, ImagePredicates.orderByName(pageable)); 
    } 

ImagePredicates.orderByName (Pageable의) :

스프링 데이터 JPA 저장소 : 생성자에 autowire가 ImageRepository있다

public interface ImageRepository extends JpaRepository<WAHImage, Long>, 
     QueryDslPredicateExecutor<WAHImage> { 
    Page<WAHImage> findAllByIsDeleted(boolean isDeleted, Pageable page); 
} 

봄 부팅 (1.5.1) 서비스,

static QPageRequest orderByName(Pageable page) { 

    QWAHImage image = QWAHImage.wAHImage; 
    QWACensusImpl name = image.census; 
    QSpecimenImpl specimen = image.specimen; 
    OrderSpecifier genus = name.name1.coalesce(specimen.genus).asc(); 
    OrderSpecifier species = name.name2.coalesce(specimen.species).asc(); 
    OrderSpecifier rank = name.rank4.coalesce(
      name.rank3.coalesce(specimen.rank)).asc(); 
    OrderSpecifier infraspecies = name.name4.coalesce(
      name.name3.coalesce(specimen.infraspecies)).asc(); 

    OrderSpecifier[] sort = new OrderSpecifier[] { 
      genus, species, rank, infraspecies 
    }; 

    return new QPageRequest(page.getPageNumber(), page.getPageSize(), sort); 
} 

컨트롤러 :

@Controller 
public class ImageController { 
    @GetMapping("/list") 
    public String list(Pageable pageable, Model model) { 
     Page<WAHImage> searchResult = imageService.get(pageable); 
    } 
} 

오류 : WAHImage 모델 클래스의

org.springframework.data.mapping.PropertyReferenceException: No property coalesce(wAHImage found for type WAHImage! 
at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:77) 
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:329) 
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:309) 
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:272) 
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:243) 
at org.springframework.data.jpa.repository.query.QueryUtils.toJpaOrder(QueryUtils.java:542) 
at org.springframework.data.jpa.repository.query.QueryUtils.toOrders(QueryUtils.java:496) 
at org.springframework.data.jpa.repository.query.JpaQueryCreator.complete(JpaQueryCreator.java:195) 
at org.springframework.data.jpa.repository.query.JpaQueryCreator.complete(JpaQueryCreator.java:143) 
at org.springframework.data.jpa.repository.query.JpaQueryCreator.complete(JpaQueryCreator.java:52) 
at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:88) 
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$QueryPreparer.createQuery(PartTreeJpaQuery.java:144) 
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.doCreateQuery(PartTreeJpaQuery.java:79) 
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.createQuery(AbstractJpaQuery.java:190) 
at org.springframework.data.jpa.repository.query.JpaQueryExecution$PagedExecution.doExecute(JpaQueryExecution.java:184) 
at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:85) 
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:116) 
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:106) 
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:483) 
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:461) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) 
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282) 
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:57) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) 
at com.sun.proxy.$Proxy143.findAllByIsDeleted(Unknown Source) 
at x.y.z.image.ImageService.get(ImageService.java:120) 
at x.y.z.image.ImageService$$FastClassBySpringCGLIB$$6d3a7999.invoke(<generated>) 
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) 
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:652) 
at x.y.z.image.ImageService$$EnhancerBySpringCGLIB$$21037cfe.get(<generated>) 
at x.y.z.controller.image.ImageController.list(ImageController.java:132) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:498) 
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) 
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133) 
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:116) 
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) 
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) 
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) 
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963) 
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) 
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) 
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) 

관련 부품. QWAHImage QueryDSL 클래스의

@Entity 
@Table(name = "image") 
public class WAHImage extends PersistentImpl { 
    private WACensusImpl census = new WACensusImpl(); 
    private SpecimenImpl specimen = new SpecimenImpl(); 
    private boolean isDeleted = Boolean.FALSE; 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "census_id", nullable = true) 
    public WACensusImpl getCensus() { 
     return census; 
    } 

    public void setCensus(WACensusImpl census) { 
     this.census = census; 
    } 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "specimen_id", nullable = true) 
    public SpecimenImpl getSpecimen() { 
     return specimen; 
    } 

    public void setSpecimen(SpecimenImpl specimen) { 
     this.specimen = specimen; 
    } 

    @Column(name = "is_deleted") 
    public boolean getIsDeleted() { 
     return isDeleted; 
    } 

    public void setIsDeleted(boolean isDeleted) { 
     this.isDeleted = isDeleted; 
    } 

} 

관련 부품. QWACensusImpl의

/** 
* QWAHImage is a Querydsl query type for WAHImage 
*/ 
@Generated("com.querydsl.codegen.EntitySerializer") 
public class QWAHImage extends EntityPathBase<WAHImage> { 

    public static final QWAHImage wAHImage = new QWAHImage("wAHImage"); 

    public final x.y.z.db.impl.QPersistentImpl _super = new x.y.z.db.impl.QPersistentImpl(this); 

    public final x.y.z.reference.census.impl.QWACensusImpl census; 

    //inherited 
    public final NumberPath<Long> id = _super.id; 

    public final BooleanPath isDeleted = createBoolean("isDeleted"); 

    public final x.y.z.reference.specimen.impl.QSpecimenImpl specimen; 
} 

관련 부품 : 일부 광범위한 배경 조사 후

/** 
* QWACensusImpl is a Querydsl query type for WACensusImpl 
*/ 
@Generated("com.querydsl.codegen.EntitySerializer") 
public class QWACensusImpl extends EntityPathBase<WACensusImpl> { 

    public static final QWACensusImpl wACensusImpl = new QWACensusImpl("wACensusImpl"); 

    public final x.y.z.db.impl.QPersistentWithIDImpl _super = new x.y.z.db.impl.QPersistentWithIDImpl(this); 

    //inherited 
    public final NumberPath<Long> id = _super.id; 

    public final StringPath name1 = createString("name1"); 

    public final StringPath name2 = createString("name2"); 

    public final StringPath name3 = createString("name3"); 

    public final StringPath name4 = createString("name4"); 

    // extraneous parts omitted. 
} 
+0

'findAllByIsDeleted 당신의'Pageable' 모델을 노출시켜주십시오 (...)'방법 이행. –

+0

'Pageable'은 표준 org.springframework.data.domain입니다.Pageable은 Spring에 의해'ImageController'에 제공되고, 보통 Spring의 PageRequest 인스턴스입니다. 'ImageRepository'는 [Spring Data JpaRepository] (http://docs.spring.io/spring-data/jpa/docs/1.11.1.RELEASE/reference/html/#repositories.core-concepts)입니다. 구현에 의해, Spring Data는 이에 대한 구체적인 클래스를 자동으로 생성합니다. – ben3000

+0

전체 엔티티 코드를 입력하고 QWACensusImpl 엔티티도 입력하십시오. –

답변

0

, 내 사용 사례가 a long history을 가지고 있으며 common one을 유지 나타납니다.

는이 문제를 해결하기 위해, 나는 수의 (a) get access to the EntityManager Spring Data JPA와 그 후 내가 ImagePredicates.orderByName(Pageable)COALESCE 키워드를 사용할 수 있어야합니다, LEFT JOINs으로 쿼리를 작성 거기에서. 또한

, (그리고 내가 사용하기로 결정했습니다 접근) 내가 ImageRepository.findAllByIsDeleted(boolean, Pageable)에 봄 데이터 @query를 사용

public interface ImageRepository extends JpaRepository<WAHImage, Long>, 
     QueryDslPredicateExecutor<WAHImage> { 
    @Query("select i from WAHImage i " + 
      "left join i.specimen s " + 
      "left join i.census c " + 
      "left join i.author a " + 
      "left join i.copyright co " + 
      "left join i.allowedUse au " + 
      "where i.isDeleted = ?1 " + 
      "order by coalesce(s.genus, c.name1) asc, " + 
      "coalesce(s.species, c.name2) asc, " + 
      "coalesce(s.infraspecies, c.name4, c.name3) asc") 
    Page<WAHImage> findAllByIsDeleted(boolean isDeleted, Pageable page); 
} 
관련 문제