当前位置: 首页 > 知识库问答 >
问题:

Spring Boot、Hibernate、querydsl:antlr.noviableAltException:意外令牌

荆钱明
2023-03-14

我目前正在用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将创建groupgroup1,但事实并非如此。那么,这些错误可能来自哪里,以及如何防止/修复它们,有什么想法吗?

实体:

@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());
    }
}

共有1个答案

陶征
2023-03-14

我仍然不明白为什么通过查询DSL生成的group的类名是group1,但是结合我的GenericPredicateBuilderGenericPredicate,会导致不一致的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值。 斯纳克斯。 编辑: 我试过?及其工作良好,但我想用来实现这一点。