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
相关产品推荐
相关产品推荐

