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来定义它?
所以我在下面有以下查询:
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"排序结果的要求的替代解决方案.
任何帮助将不胜感激.提前致谢.
缺口
我已经构建了一个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实现连接操作的正确方法是什么?
谢谢
我正在尝试用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) 我在我的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中是否可行?
我正在使用动态过滤器过滤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) …
我有一个问题是使用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) 我试图在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 | * …
我正在尝试使用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) 我和实体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 …
querydsl ×10
java ×4
hibernate ×3
spring ×3
jpa ×2
sql ×2
casting ×1
dictionary ×1
dynamic ×1
gradle ×1
mongodb ×1
path ×1
spring-boot ×1
spring-data ×1
syntax ×1