我目前正在用spring boot、hibernate和QueryDSL开发一个数据仓库。几乎一切都很好,但是我在执行一个名为group
的实体的搜索请求时遇到了麻烦。这些错误并没有真正的帮助:
我的请求很简单/group/advancedsearch?page=0&size=10&sort=name,asc&search=groupcode:dfa,name:dfa,
antlr.NoViableAltException: unexpected token: group
[...]
java.lang.NullPointerException: null
为了使这一点更容易理解,我的代码如下所示。我对我的大多数实体都有同样的方法,而且效果很好。因为我不知道意外标记组
可能来自哪里,所以我查看了生成的类QGroup
,在那里我发现了代码的平静public static final QGroup group=new QGroup(“group1”);
。名称group1
让我很好奇,但我不确定它是否与错误有关。在所有其他类中,字符串总是类的名称,首字母很小。
我认为实体group
可能是重复的,所以querydsl将创建group
和group1
,但事实并非如此。那么,这些错误可能来自哪里,以及如何防止/修复它们,有什么想法吗?
实体:
@Entity
@Table(name = "[Group]")
public class Group {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "Group_ID")
private long groupId;
@ManyToOne()
@JoinColumn(name = "Dimension_ID")
private Dimension dimension;
@Column(name = "Dimension_ID", updatable = false, insertable = false)
private Long dimensionId;
@Column(name = "GroupCode")
private String groupCode;
@Column(name = "Name")
private String name;
[...]
}
出现错误时控制器的功能:
@RequestMapping(value = GROUP_URL + "/advancedSearch", method = RequestMethod.GET)
@ResponseBody
public PagedResources<Group> advancedSearch(
@RequestParam(value = "search", required = false) String search,
Pageable pageable, @RequestParam MultiValueMap<String, String> parameters,
PersistentEntityResourceAssembler persistentEntityResourceAssembler
) {
SimpleGrantedAuthority[] allowedRoles = {SYSADMIN};
GeneralPredicateBuilder<Group> builder = new GeneralPredicateBuilder<>(Group.class);
Predicate predicate = predicateService.getPredicateFromParameters(parameters, Group.class);
Page<Group> results = service.advancedSearch(
this.buildAdvancedSearch(search, predicate, builder), pageable, allowedRoles);
return super.toPagedResource(results, persistentEntityResourceAssembler);
}
public Predicate buildAdvancedSearch(String search, Predicate predicate, GeneralPredicateBuilder<T> builder) {
if (search != null) {
Pattern pattern = Pattern.compile("(\\w+?)(:|<|>)(\\w+?),");
Matcher matcher = pattern.matcher(search + ",");
while (matcher.find()) {
builder.with(matcher.group(1), matcher.group(2), matcher.group(3));
}
BooleanExpression expression = builder.build();
if (predicate != null) {
predicate = expression.and(predicate);
} else {
predicate = expression;
}
}
return predicate;
}
predicateService
:
@Service
public class PredicateService {
@Autowired
private final QuerydslPredicateBuilder querydslPredicateBuilder;
@Autowired
private final QuerydslBindingsFactory querydslBindingsFactory;
public PredicateService(QuerydslPredicateBuilder querydslPredicateBuilder, QuerydslBindingsFactory querydslBindingsFactory) {
this.querydslPredicateBuilder = querydslPredicateBuilder;
this.querydslBindingsFactory = querydslBindingsFactory;
}
public <T> Predicate getPredicateFromParameters(final MultiValueMap<String, String> parameters, Class<T> tClass) {
TypeInformation<T> typeInformation = ClassTypeInformation.from(tClass);
return querydslPredicateBuilder.getPredicate(typeInformation, parameters, querydslBindingsFactory.createBindingsFor(typeInformation));
}
}
public Page<Group> advancedSearch(Predicate predicate, Pageable pageable, SimpleGrantedAuthority[] roles){
if (SecurityUtils.userHasAnyRole(roles)) {
return this.repository.findAll(predicate, pageable); // <-- here the errors raise
} else throw new ForbiddenException(FORBIDDEN);
}
@RepositoryRestResource(collectionResourceRel = GROUP_URL, path = GROUP_URL)
@CrossOrigin(exposedHeaders = "Access-Control-Allow-Origin")
public interface GroupRepository extends PagingAndSortingRepository<Group, Long>, JpaSpecificationExecutor<Group>, QuerydslPredicateExecutor<Group> {
}
@Generated("com.querydsl.codegen.EntitySerializer")
public class QGroup extends EntityPathBase<Group> {
private static final long serialVersionUID = 384278695L;
private static final PathInits INITS = PathInits.DIRECT2;
public static final QGroup group = new QGroup("group1"); // <-- this is confusing
[...]
select group1
from Group group1
where ?1 = ?1 and lower(group.groupCode) like ?2 escape '!'
更新2[2020-02-14]:
GeneralPredicateBuilder:
public class GeneralPredicateBuilder<T> {
private List<SearchCriteria> params;
private final Class<T> type;
public GeneralPredicateBuilder(Class<T> type) {
this.params = new ArrayList<>();
this.type = type;
}
public GeneralPredicateBuilder<T> with(String key, String operation, Object value) {
params.add(new SearchCriteria(key, operation, value));
return this;
}
public BooleanExpression build() {
if (params.size() == 0) {
return null;
}
List<BooleanExpression> predicates = params.stream().map(param -> {
GeneralPredicate<T> predicate = new GeneralPredicate<T>(param, type);
BooleanExpression tmp = predicate.getPredicate();
return tmp;
}).filter(Objects::nonNull).collect(Collectors.toList());
BooleanExpression result = Expressions.asBoolean(true).isTrue();
for (BooleanExpression predicate : predicates) {
result = result.and(predicate);
}
return result;
}
public List<Predicate> buildPredicate(){
if (params.size() == 0) {
return null;
}
return params.stream().map(param -> {
GeneralPredicate<T> predicate = new GeneralPredicate<>(param, type);
return predicate.getPredicate();
}).filter(Objects::isNull).collect(Collectors.toList());
}
}
我仍然不明白为什么通过查询DSL生成的group
的类名是group1
,但是结合我的GenericPredicateBuilder
和GenericPredicate
,会导致不一致的sql,如问题所示。但我最终能够解决这个问题,不幸的是,以一种非常肮脏的方式。为了完整起见,这里是我的generalpredicate
:
public class GeneralPredicate<T> {
private SearchCriteria searchCriteria;
private final Class<T> type;
private final String variable;
public GeneralPredicate(SearchCriteria param, Class<T> type) {
searchCriteria = param;
this.type = type;
if(type.getSimpleName().equals("Group")){
this.variable = "group1";
} else {
this.variable = type.getSimpleName().replaceFirst("" + type.getSimpleName().charAt(0), "" + type.getSimpleName().charAt(0)).toLowerCase();
}
}
public BooleanExpression getPredicate() {
PathBuilder<T> entityPath = new PathBuilder<T>(type, variable);
if (isNumeric(searchCriteria.getValue().toString())) {
NumberPath<Integer> path = entityPath.getNumber(searchCriteria.getKey(), Integer.class);
int value = Integer.parseInt(searchCriteria.getValue().toString());
switch (searchCriteria.getOperation()) {
case ":":
return path.eq(value);
case ">":
return path.goe(value);
case "<":
return path.loe(value);
}
} else {
StringPath path = entityPath.getString(searchCriteria.getKey());
switch (searchCriteria.getOperation()) {
case ":":
return path.containsIgnoreCase(searchCriteria.getValue().toString());
case "<":
return path.startsWith(searchCriteria.getValue().toString());
case ">":
return path.endsWith(searchCriteria.getValue().toString());
}
}
return null;
}
}
您可以在构造函数中找到脏修复。我真的很讨厌它,但它正在工作,生成的sql也没问题。
也许我用了一个错误的方法。我愿意接受建议。
我必须获得我的数据库(PostgreSQL)中的所有注册表,并使用不带大小写的。我试过使用标准,但ignoreCase()对我不起作用(我使用的是Hibernate3.6)。 我也尝试过使用ilike方法,但仍然不起作用。 这个版本也是: 因此,当我尝试在Hibernate中使用HQL创建查询时,会出现以下错误: 我的代码如下所示: 我做错了什么?
问题内容: 我有一个查询,我正在联接两个表ROuteMaster和RouteHalts。当我执行内部联接时 我搜索了该网站,发现了类似的问题及其答案。提到的问题是 我在RouteHalts中为RouteMaster进行了多对一映射,在RouteHalts中为RouteMaster定义了getter和setter方法 但仍然出现相同的错误。可以请一个人来指导我。 映射文件 公共类RouteMaste
嗨,我使用Spring mvc 3 和Hibernate 4 开发一个 Web 应用程序。我正在为所有配置使用注释。 当我尝试选择一个实体时,出现错误: 如果我用< code >进行查询。create SQL query() hibernate返回一个< code>ClanMember实体的< code>Object[]实例。 道中的方法: 实体: 表 CLAN_MEMBERS: 我做错了什么?先
问题内容: 为什么每次我做时:- 它只是解析很好,但是当我这样做时:- 它给我一个错误,说:- 问题答案: 您要它解析JSON文本(不是)。那是无效的JSON,字符串必须用双引号引起来。 如果要与第一个示例等效:
本文向大家介绍意外的令牌相关面试题,主要包含被问及意外的令牌时的应答技巧和注意事项,需要的朋友参考一下 您的JavaScript表示使用JSONP模式发出Ajax请求(这涉及将元素插入文档中而不是使用XMLHttpRequest)。 您得到的响应是一个XML文档,而不是遵循JSONP模式的JavaScript程序,它类似于: 因为浏览器试图将XML作为JavaScript执行(不是),您会收到错误
My HQL: 我收到以下错误: 我是HQL的新手。我想通过代码动态设置间隔值。我设置了等于比较的参数值。我读过http://www.mkyong.com/hibernate/hibernate-parameter-binding-examples/post,但我不知道在没有其他符号的情况下如何设置timeOffSet值。 斯纳克斯。 编辑: 我试过?及其工作良好,但我想用来实现这一点。