我当前正在修改一个在内存模型中与JENA一起使用的程序,但是当我尝试使用TDB来存储不同的命名模型时却中断了。我认为最终的行为是JENA中的错误,但也许我对同一TDB中命名模型的假设是错误的。
为了展示这种行为,假设我填充了一个模型,然后将其复制到另一个模型。
private void init(Model aBox) {
aBox.setNsPrefix("foaf", FOAF.getURI());
aBox.createResource("http://kaiko.getalp.org/test_person__1", FOAF.Person);
aBox.createResource("http://kaiko.getalp.org/test_person__2", FOAF.Person);
aBox.createResource("http://kaiko.getalp.org/test_person__3", FOAF.Person);
}
private void copy(Model aBox, Model xBox) {
StmtIterator persons =
aBox.listStatements(null, RDF.type, FOAF.Person);
while (persons.hasNext()) {
Statement next = persons.next();
Resource p = xBox.createResource(next.getSubject().getURI());
xBox.add(xBox.createStatement(p, RDF.type, FOAF.Person));
}
}
我现在在默认模型上应用此行为,它似乎按预期工作。
@Test
public void concurrentModifWhenNoModif() throws IOException {
Model aBox = ModelFactory.createDefaultModel();
Model xBox = ModelFactory.createDefaultModel();
init(aBox);
copy(aBox, xBox);
}
但是当我尝试使用由同一TDB支持的2个模型时,它会引发ConcurrentModificationException
:
@Test
public void concurrentModifWhenNoModifOnTDB() throws IOException {
Path temp = Files.createTempDirectory("jenatest");
temp.toFile().deleteOnExit();
String tdbDir = temp.toAbsolutePath().toString();
Dataset dataset = TDBFactory.createDataset(tdbDir);
Model aBox = dataset.getNamedModel("MyNamedModel/");
Model xBox = dataset.getNamedModel("OtherNamedModel");
init(aBox);
copy(aBox, xBox);
}
[我的理解是,我在aBox模型上进行了迭代,并对xBox模型进行了修改,但我不明白为什么它们共享一个公共TDB后端这一事实使它们在模型级别上相互依赖。
dataset.getNamedModel
返回数据集中数据的视图,并且不将数据复制出去。 aBox
和xBox
共享数据集。应用程序无法同时迭代和更新数据库。
实际上,在耶拿的许多地方都是如此,因为模型可以是其他模型的组合,因此可以共享数据(例如,推理模型)。>>
有一项操作model1.add(model2)
,将一个模型复制到另一个模型。