You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot整合Apache Jena与OpenLink Virtuoso测试问题排查

SpringBoot 2.7整合Apache Jena+Virtuoso:SPARQL查询ResultSet.getRowNumber()始终返回0的问题

问题背景

基于SpringBoot 2.7开发整合Apache Jena与OpenLink Virtuoso的应用,按官方文档完成以下操作后测试失败:

  • 配置POM依赖,引入virtjdbc4、virt_jena3及apache-jena-libs
  • 在application.properties中配置Virtuoso连接信息
  • 创建返回VirtGraph的Spring Bean
  • 编写测试用例执行SPARQL查询,断言ResultSet.getRowNumber() > 0,但测试失败且无日志/异常抛出

补充信息:Virtuoso的1111端口连通性正常,后续确认查询本身可正常执行,但getRowNumber()始终返回0。


关键配置代码

1. POM依赖配置

<dependencies>
    <!-- Virtuoso JDBC驱动 -->
    <dependency>
        <groupId>com.openlinksw</groupId>
        <artifactId>virtjdbc4</artifactId>
        <version>4.2.0</version>
    </dependency>
    <!-- Virtuoso与Jena3的整合包 -->
    <dependency>
        <groupId>com.openlinksw</groupId>
        <artifactId>virt_jena3</artifactId>
        <version>4.2.0</version>
    </dependency>
    <!-- Apache Jena核心依赖 -->
    <dependency>
        <groupId>org.apache.jena</groupId>
        <artifactId>apache-jena-libs</artifactId>
        <version>4.6.1</version>
        <type>pom</type>
    </dependency>
</dependencies>

2. Virtuoso连接配置(application.properties)

# Virtuoso连接信息
virtuoso.url=jdbc:virtuoso://localhost:1111
virtuoso.username=dba
virtuoso.password=dba

3. VirtGraph Spring Bean配置

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.hp.hpl.jena.graph.Graph;
import com.openlinksw.basic.virtjena.VirtGraph;

@Configuration
public class VirtuosoConfig {
    @Value("${virtuoso.url}")
    private String virtuosoUrl;
    @Value("${virtuoso.username}")
    private String username;
    @Value("${virtuoso.password}")
    private String password;

    @Bean
    public Graph virtGraph() {
        return new VirtGraph(virtuosoUrl, username, password);
    }
}

问题根源

测试用例中误用了ResultSet.getRowNumber()方法:

  • Jena的ResultSet实现遵循JDBC规范,初始状态下游标位于第一行之前,此时getRowNumber()返回0
  • 只有调用next()方法将游标移动到结果行后,getRowNumber()才会返回当前行的索引(从1开始计数)
  • 原测试用例未移动游标直接调用getRowNumber(),因此始终得到0,导致断言失败

修正后的测试用例

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import com.hp.hpl.jena.graph.Graph;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.ResultSet;
import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
public class VirtuosoQueryTest {
    @Autowired
    private Graph virtGraph;

    @Test
    public void testSparqlQuery() {
        String sparqlQuery = "SELECT ?s ?p ?o WHERE { ?s ?p ?o } LIMIT 10";
        Query query = QueryFactory.create(sparqlQuery);
        
        try (QueryExecution qe = QueryExecutionFactory.create(query, virtGraph)) {
            ResultSet resultSet = qe.execSelect();
            
            // 方式1:移动游标后断言行号
            if (resultSet.hasNext()) {
                resultSet.next();
                assertTrue(resultSet.getRowNumber() > 0);
            }
            
            // 方式2:统计结果行数(更直观)
            int rowCount = 0;
            while (resultSet.hasNext()) {
                resultSet.next();
                rowCount++;
            }
            assertTrue(rowCount > 0);
        }
    }
}

内容的提问来源于stack exchange,提问作者Discipulos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 17:57:59