我正在按照

运行 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> 

在执行 native 查询时,使用以下内容,

    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)  

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

请您参考如下方法:

来自GitHub's page on Parboiled parser很明显:

The parser classes created by parboiled for Java are not thread-safe.

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

尝试使用命名查询。使用注释,它会是这样的:

@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 映射文件中应该有定义这些注释的示例。

(但是请记住,我没有测试过这段代码,我脑海中的一个问题是您是否必须在 native 查询中转义冒号)。

HTH


评论关闭
IT干货网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!