标签: querydsl

如何使用Spring JPA进行分页QueryDSL查询?

QueryDSL定义了一个OrderSpecifier接口,通过调用asc()或者可以很容易地获得任何字段的实例desc().QueryDslPredicateExecutorSpring Data JPA 的界面甚至有一个findAll()OrderSpecifiers为参数的方法.

org.springframework.data.domain.PageRequest但是对QueryDSL一无所知,它有自己定义查询排序顺序的方法,即org.springframework.data.domain.Sort.它可以包含org.springframework.data.domain.Sort.Order许多OrderSpecifiers,它们很像s,除了它们不是类型安全的等等.

所以,如果我想制作使用排序的分页查询,是否真的没有办法使用QueryDSL来定义它?

spring querydsl spring-data-jpa

6
推荐指数
3
解决办法
4782
查看次数

如何在SpringData和QueryDsl中指定多列OrderSpecifier?这可能吗

所以我在下面有以下查询:

public Iterable<Dealer> findAll(Dealer dealer) {
    QDealer qdealer = QDealer.dealer;

    BooleanExpression where = null;
    if(dealer.getId() != null && dealer.getId() != 0) {
        buildPredicate(qdealer.id.goe(dealer.getId()));
    }

    OrderSpecifier<String> sortOrder = QDealer.dealer.dealerCode.desc();
    Iterable<Dealer> results = dlrRpstry.findAll(where, sortOrder); 
    return results;
}
Run Code Online (Sandbox Code Playgroud)

上面的查询工作正常.但是,我想首先按dealerType对结果进行排序,然后由dealerCode对结果进行排序,有点像"由dealerType asc,dealerCode desc订购".如何实例化OrderSpecifier,以便结果将按dealerType排序,然后按经销商代码排序.

DealerRepository dlrRpstry扩展了JpaRepository,QueryDslPredicateExecutor

我使用的是spring-data-jpa-1.1.0,spring-data-commons-dist-1.3.2和querydsl-jpa-2.9.0.

如果OrderSpecifier不能配置为多列排序顺序,那么将满足我对"by dealerType asc,dealerCode desc"排序结果的要求的替代解决方案.

任何帮助将不胜感激.提前致谢.

缺口

querydsl spring-data-jpa

6
推荐指数
1
解决办法
1万
查看次数

使用QueryDSL和Spring的Repository编写跨表查询

我已经构建了一个DAL,它使用Spring的存储库通过Hibernate和JPA管理MySQL DB上的CRUD操作.特别是这是我的Repository定义

package my.dal.repository;

import my.domain.dal.User;

import org.springframework.data.querydsl.QueryDslPredicateExecutor;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;


@Repository
public interface IUserRepository extends CrudRepository<User, String>, QueryDslPredicateExecutor<User>{

}
Run Code Online (Sandbox Code Playgroud)

通过这个定义,我能够通过扩展QueryDslPredicateExecutor接口和findAll(Predicate)方法使用QueryDSL Predicates执行CRUD操作.

我面临的问题是,这种方式我无法进行跨表查询.实际上,我不能使用QueryDSL的连接工具,因为我没有HibernateQuery.

使用Spring Repositories和QueryDSL实现连接操作的正确方法是什么?

谢谢

java spring querydsl spring-data

6
推荐指数
1
解决办法
1029
查看次数

覆盖使用EntityGraph注释的Spring-Data-JPA默认方法会导致QueryException

我正在尝试用Data-JPA实现一个EntityGraph,因为使用QueryDslPredicateExecutor<T>暴露方法findAll(Predicate, Pageable)我需要的那个,我试图覆盖它注释@EntityGraph然后麻烦开始它抛出:

org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.QueryException: query specified join fetching, but the owner of the fetched association was not present in the select list [FromElement{explicit,not a collection join,fetch join,fetch non-lazy properties,classAlias=appointment,role=com.physioclinic.entity.Appointment.createdBy,tableName=user,tableAlias=user5_,origin=appointment appointmen0_,columns={appointmen0_.createdBy_id ,className=com.physioclinic.entity.User}}] [select count(appointment)
from com.physioclinic.entity.Appointment appointment where lower(concat(concat(appointment.patient.person.name,?1),appointment.patient.person.surname)) like ?2 escape '!']; nested exception is java.lang.IllegalArgumentException: org.hibernate.QueryException: query specified join fetching, but the owner of the fetched association was not present in the select list [FromElement{explicit,not a collection join,fetch join,fetch non-lazy properties,classAlias=appointment,role=com.physioclinic.entity.Appointment.createdBy,tableName=user,tableAlias=user5_,origin=appointment appointmen0_,columns={appointmen0_.createdBy_id ,className=com.physioclinic.entity.User}}] …
Run Code Online (Sandbox Code Playgroud)

querydsl spring-data-jpa

6
推荐指数
1
解决办法
2794
查看次数

QueryDsl - 基于密钥过滤Map

我在我的hibenrate实体类中有以下属性:

@MapKeyJoinColumn(name = "language_code")
@LazyCollection(LazyCollectionOption.EXTRA)
@ElementCollection(fetch = FetchType.LAZY)
@CollectionTable(name = "text_translations", joinColumns = @JoinColumn(name = "text_id"))
private Map<Language, String> translations = new HashMap<>();
Run Code Online (Sandbox Code Playgroud)

现在我想查询这个实体并按用户的语言过滤地图内容(即按地图的键).我有以下加入我的查询:

StringPath titleTran = new StringPath("title_tran");
from(entity).
.leftJoin(entity.translations, titleTran).fetch().where(?mapKey?.eq(userLanguage));
Run Code Online (Sandbox Code Playgroud)

我需要的是什么?mapKey?通过titleTran路径的语言路径.这在QueryDsl中是否可行?

java sql dictionary hibernate querydsl

6
推荐指数
1
解决办法
1174
查看次数

QueryDSL + PathBuilder +强制转换为字符串

我正在使用动态过滤器过滤PrimeFaces DataTables org.springframework.data.jpa.domain.Specification.我使用Spring工作.现在我想知道如何使用QueryDSL做同样的事情.

使用规范我可以javax.persistence.criteria.Root用来获取javax.persistence.criteria.Join,用于javax.persistence.criteria.Expression.as(Class<String> type)将它转换为String并最终使用javax.persistence.criteria.CriteriaBuilder.like(Expression<String> x, String pattern, char escapeChar).

我如何在QueryDSL中做同样的事情?我可以使用PathBuilder new PathBuilder<T>(clazz, "entity")(你真的必须在这里使用变量吗?我希望我的类是通用的......)然后com.mysema.query.types.path.PathBuilder.get(String property)返回新的PathBuilder而不是Expression.

如果我尝试使用com.mysema.query.types.path.PathBuilder.getString(String property)我得到java.lang.IllegalArgumentException: Parameter value [1] did not match expected type [java.lang.Integer].

似乎我失踪的那部分是演员.我很确定有人正在处理同样的事情.

谢谢.

编辑:IllegalArgumentException的堆栈跟踪

尝试在整数列中搜索文本"1" com.mysema.query.types.path.PathBuilder.getString(String property)- 这就是我需要进行强制转换的地方:

Caused by: java.lang.IllegalArgumentException: Parameter value [1] did not match expected type [java.lang.Integer] at org.hibernate.ejb.AbstractQueryImpl.validateParameterBinding(AbstractQueryImpl.java:375) at org.hibernate.ejb.AbstractQueryImpl.registerParameterBinding(AbstractQueryImpl.java:348) at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:375) at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:442) at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:72) at com.mysema.query.jpa.impl.JPAUtil.setConstants(JPAUtil.java:44) at com.mysema.query.jpa.impl.AbstractJPAQuery.createQuery(AbstractJPAQuery.java:130) at com.mysema.query.jpa.impl.AbstractJPAQuery.createQuery(AbstractJPAQuery.java:97) at com.mysema.query.jpa.impl.AbstractJPAQuery.list(AbstractJPAQuery.java:240) …

casting path dynamic querydsl

6
推荐指数
1
解决办法
5534
查看次数

Spring JPA deleteInBatch导致StackOverflow

我有一个问题是使用deleteInBatch从db中删除项目.我有一个对象A有一个对象B列表,如:

class A {
private List <B>;
}
Run Code Online (Sandbox Code Playgroud)

该列表包含7k多个元素.所以现在我必须删除A及其所有元素.我试过通过deleteInBatch,但我得到了

org.springframework.web.util.NestedServletException: Handler processing failed;
nested exception is java.lang.StackOverflowError
Run Code Online (Sandbox Code Playgroud)

使用sipmle delete方法删除项目有效,但需要5分钟以上.我的删除代码是:

public void delete(Long id) {
A a = repository.findOne(id);
deleteElements(a);
repository.delete(a);
}

private void deleteElements(A a) {
repository.deleteInBatch(a.getListOfB);
}
Run Code Online (Sandbox Code Playgroud)

有没有一个很好的解决方案来加快删除过程或如何更改,以便deleteinbatch不占用所有休眠堆栈 - 不增加它?

完整的Stacktrace:

org.springframework.web.util.NestedServletException: Handler processing failed; nested exception is java.lang.StackOverflowError
org.springframework.web.servlet.DispatcherServlet.triggerAfterCompletionWithError(DispatcherServlet.java:1259)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:945)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:163)
net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:206)
net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:179)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
Run Code Online (Sandbox Code Playgroud)

等等...

root cause

java.lang.StackOverflowError
org.hibernate.hql.internal.ast.tree.SqlNode.<init>(SqlNode.java:34)
sun.reflect.GeneratedConstructorAccessor36.newInstance(Unknown Source)
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
java.lang.reflect.Constructor.newInstance(Constructor.java:526)
java.lang.Class.newInstance(Class.java:379)
org.hibernate.hql.internal.ast.SqlASTFactory.create(SqlASTFactory.java:256)
antlr.ASTFactory.create(ASTFactory.java:153)
antlr.ASTFactory.create(ASTFactory.java:186) …
Run Code Online (Sandbox Code Playgroud)

java spring hibernate querydsl spring-data-jpa

6
推荐指数
1
解决办法
2143
查看次数

具有元组条件的QueryDSL和SubQuery

我试图在QueryDSL中编写一个查询来获取由其parentId分组的表中最旧的元素.

SQL等价物应该是:

SELECT a.* FROM child a
    INNER JOIN
    (
        SELECT parentId, MAX(revision) FROM child GROUP BY parentId
    ) b
    ON ( 
        a.parentId = b.parentId AND a.revision = b.revision
    )
Run Code Online (Sandbox Code Playgroud)

现在在QueryDSL中,我坚持使用语法.

JPQLQuery<Tuple> subquery = JPAExpressions
                .select(child.parent, child.revision.max())
                .from(child)
                .groupBy(child.parent);

HibernateQuery<Child> query = new HibernateQuery<>(session);
query.from(child)
    .where(child.parent.eq(subquery.???).and(child.revision.eq(subquery.???))));
Run Code Online (Sandbox Code Playgroud)

如何使用子查询编写此查询?

表格看起来像这样:

___parent___ (not used in this query, but exists)
parentId
P1       | *
P2       | *
P3       | *

___child___
parentId | revision
P1       | 1       | *
P1       | 2       | * …

java syntax hibernate jpa querydsl

6
推荐指数
1
解决办法
2244
查看次数

Spring Boot MongoDb QueryDSL Gradle Intellij Integration用于生成QueryDSL Q类

我正在尝试使用Spring Boot项目中的gradle为我的Mongo实体生成QueryDSL Q类.我正在使用的IDE是Intellij.

我正在使用的代码改编自本主题从Gradle构建脚本生成JPA2 Metamodel:

sourceSets {
    generated {
        java {
            srcDirs = ['src/generated/java']
        }
    }
}

configurations {
    querydslapt
}

task generateQueryDSL(type: JavaCompile, group: 'build', description: 'Generates the QueryDSL query types') {
    source = sourceSets.main.java
    classpath = configurations.compile + configurations.querydslapt
    options.compilerArgs = [
            "-proc:only",
            "-processor", "org.springframework.data.mongodb.repository.support.MongoAnnotationProcessor"
    ]
    destinationDir = sourceSets.generated.java.srcDirs.iterator().next()
}

compileJava {
    dependsOn generateQueryDSL
    source  generateQueryDSL.destinationDir
}

compileGeneratedJava {
    dependsOn generateQueryDSL
    options.warnings = false
    classpath += sourceSets.main.runtimeClasspath
}

clean {
    delete sourceSets.generated.java.srcDirs
}

idea {
    module …
Run Code Online (Sandbox Code Playgroud)

intellij-idea mongodb gradle querydsl spring-boot

6
推荐指数
0
解决办法
436
查看次数

QueryDsl:与投影bean和oneToMany或manyToMany关联的异常"参数类型不匹配"

我和实体manyToMany之间有关联(> --- < )UserRoleUserRole

我想执行此查询:

createQuery()
        .from(qUser)
        .leftJoin(qUser.roles, qRole)
        .where(qUser.login.eq(login))
        .singleResult(
                Projections.bean(User.class,
                        qUser.id,
                        qUser.login,
                        qUser.password,
                        GroupBy.set(Projections.bean(Role.class,
                                qRole.id,
                                qRole.code
                        )).as(qUser.roles)
                )
        );
Run Code Online (Sandbox Code Playgroud)

生成的查询看起来像这样,对我来说它是完美的:

SELECT user0_.ID AS col_0_0_,
       user0_.LOGIN AS col_1_0_,
       user0_.PASSWORD AS col_2_0_,
       role2_.ID AS col_4_0_,
       role2_.CODE AS col_5_0_
FROM public.USER user0_
LEFT OUTER JOIN public.USER_ROLE roles1_ ON user0_.ID=roles1_.USER_ID
LEFT OUTER JOIN public.ROLE role2_ ON roles1_.ROLE_ID=role2_.ID
WHERE user0_.LOGIN=? LIMIT ?
Run Code Online (Sandbox Code Playgroud)

但我有一个java.lang.IllegalArgumentException: argument type mismatch.

我调试了,我发现数据库id中的数据加载没有问题.这是在QueryDsl/Hibernate做一些内省来创建和初始化我抛出异常的实体的时候.

问题是该User.setRoles(Set<Role>)方法使用long参数调用:第一个Role实体列表的ID User …

sql jpa querydsl

6
推荐指数
1
解决办法
717
查看次数