代码之家  ›  专栏  ›  技术社区  ›  Evan Knowles

间歇Mongo/JPA IllegalargumentException解析地理本地查询

  •  0
  • Evan Knowles  · 技术社区  · 6 年前

    我在跑步 mongo-java-driver 按照

        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongo-java-driver</artifactId>
            <version>3.7.0</version>
            <scope>compile</scope>
        </dependency>
    

    hibernate-ogm-mongodb 根据

        <groupId>org.hibernate.ogm</groupId>
        <artifactId>hibernate-ogm-bom</artifactId>
        <type>pom</type>
        <version>5.3.1.Final</version>
        <scope>import</scope>
    

    在执行本机查询时,使用以下命令,

        String query = "db.%s.find({ 'location': { '$nearSphere': { '$geometry': { 'type': 'Point', 'coordinates': [%s,%s] }, '$maxDistance': %s } } })";
        String format = String.format(query, getType().getSimpleName(), p.getX(), p.getY(), distance * 1000.0);
        try {
            Query nativeQuery = getEm().createNativeQuery(format, getType());
            return nativeQuery.getResultList();
        } catch (Exception ex) {
            System.out.println("**** Location exception on query: "+ format);
            throw ex;
        }
    

    我断断续续地得到下面的例外。我可以立即运行相同的代码,并接收有效的输出。

    javax.ejb.EJBTransactionRolledbackException: Error while parsing action 'Query/Optional/CliQueryOrJsonFindQuery/FirstOf/ParsedQuery/Db/Db_Action1' at input position (line 1, pos 3):
    db.User.find({ 'location': { '$nearSphere': { '$geometry': { 'type': 'Point', 'coordinates': [28.051258087158203,-26.135223388671875] }, '$maxDistance': 2.0 } } })
      ^
    
    java.lang.IllegalArgumentException: Cannot peek beyond the bottom of the stack
      at org.parboiled.common.Preconditions.checkArgument(Preconditions.java:79)
      at org.parboiled.support.DefaultValueStack.peek(DefaultValueStack.java:149)
      at org.parboiled.support.DefaultValueStack.peek(DefaultValueStack.java:144)
      at org.parboiled.support.DefaultValueStack.peek(DefaultValueStack.java:139)
    at org.parboiled.BaseActions.peek(BaseActions.java:260)
    

    这发生在多个不同的文档集合上,但始终是间歇性的。逐字重复该操作将导致返回有效结果。

    我以前在版本上 3.6.4 ,但我也收到了类似的错误。

    有没有迹象表明我做错了什么,或者有什么版本冲突?

    我试着在一个循环中运行以查看是否可以重新创建它,但它似乎只发生过一次-它是否与空闲时间后的某种连接超时有关?

    更新 以下内容:

    我试着通过并行运行两个线程来创建竞争条件,我确实看到了异常,尽管略有不同。

    javax.ejb.EJBException: 
    org.hibernate.ogm.datastore.mongodb.query.parsing.nativequery.impl
    .NativeQueryParseException: 
    Cli query should match the format db.collection.operation(<arguments>)
    at 
    org.jboss.as.ejb3.tx.CMTTxInterceptor.handleExceptionInOurTx
    (CMTTxInterceptor.java:187) 
    

    不过,我认为这已经足够令人信服了。

    1 回复  |  直到 6 年前
        1
  •  1
  •   diginoise    6 年前

    GitHub's page on Parboiled parser 很明显:

    parboiled for java创建的解析器类不是线程安全的。

    …这可能会在多个线程尝试执行此查询时导致问题。

    尝试改用命名查询。有了注释,它将类似于:

    @NamedNativeQueries({
      @NamedNativeQuery(
        name = "findNearSphere",
        query = "db.:dbName.find({'location': { '$nearSphere': { '$geometry': { 'type': 'Point', 'coordinates': [:xCoord,:yCoord] }, '$maxDistance': :distance } } }", resultClass = SomeResultClass.class
      )
    })
    
    getEm()
      .createNamedQuery("findNearSphere")
        .setParameter("dbName", "User")
        .setParameter("xCoord", 28.051258087158203)
        .setParameter("yCoord", -26.135223388671875)
        .setParameter("distance", 2.0)
      .getResultList(); 
    

    …希望这样可以避免每次您想发出查询时都使用解析器。

    如果不使用注释,则应该有在xml映射文件中定义这些注释的示例。

    ( 不过,请记住,我没有测试过这段代码,我的一个问题是,在本机查询中,您是否需要转义冒号 )中。

    高温高压