首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我如何“嵌套”对象与OpenRDF阿里巴巴分配资源虹膜?

我如何“嵌套”对象与OpenRDF阿里巴巴分配资源虹膜?
EN

Stack Overflow用户
提问于 2016-01-09 00:08:20
回答 2查看 142关注 0票数 2

我正在尝试将OpenRDF阿里巴巴 (与芝麻相关联)作为一种工具,将Java对象映射到RDF三元组并再次返回。目前,我正在研究它如何处理对象图。

我有两个物体,内部和外部。外部有一个内部的参考。当我持久化外部实例时,内部实例似乎总是表示为b节点,即使我以前使用分配的IRI来持久化内部实例。

我需要做什么才能自己成功地分配内部实例的IRI,而不是创建b节点呢?

额外的学分问题:我如何使资源IRI成为Java对象上的属性,而不是让它与它标识的对象并行但断开连接?

代码:

内部:

代码语言:javascript
复制
package alibabaeval.domain;

import org.openrdf.annotations.Iri;

@Iri("http://example.com/innerType")
public class Inner {

    @Iri("http://example.com/innerType/data")
    private String data;

    public Inner(String data) {
        this.data = data;
    }


    // if this is missing, an unhelpful ClassCastException will be thrown on retrieval
    public Inner() {
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }
}

外部:

代码语言:javascript
复制
package alibabaeval.domain;

import org.openrdf.annotations.Iri;

@Iri("http://example.com/outerType")
public class Outer {

    @Iri("http://example.com/outerType/data")
    private String outerData;

    @Iri("http://example.com/outerType/innerObject")
    private Inner innerObject;

    public Outer(String outerData) {
        this.outerData = outerData;
    }

    // if this is missing, an unhelpful ClassCastException will be thrown on retrieval
    public Outer() {
    }

    public String getOuterData() {
        return outerData;
    }

    public void setOuterData(String outerData) {
        this.outerData = outerData;
    }

    public Inner getInnerObject() {
        return innerObject;
    }

    public void setInnerObject(Inner innerObject) {
        this.innerObject = innerObject;
    }
}

测试计划:

代码语言:javascript
复制
package alibabaeval;

import org.junit.Test;
import org.openrdf.model.URI;
import org.openrdf.model.ValueFactory;
import org.openrdf.query.QueryLanguage;
import org.openrdf.repository.Repository;
import org.openrdf.repository.object.ObjectConnection;
import org.openrdf.repository.object.ObjectRepository;
import org.openrdf.repository.object.config.ObjectRepositoryFactory;
import org.openrdf.repository.sail.SailRepository;
import org.openrdf.rio.RDFFormat;
import org.openrdf.rio.RDFWriter;
import org.openrdf.rio.Rio;
import org.openrdf.sail.memory.MemoryStore;

import alibabaeval.domain.Inner;
import alibabaeval.domain.Outer;

public class AlibabaEval {

    public static void main(String[] args) throws Exception {
        Repository store = new SailRepository(new MemoryStore());
        store.initialize();

        // wrap in an object repository
        ObjectRepositoryFactory factory = new ObjectRepositoryFactory();
        ObjectRepository repository = factory.createRepository(store);

        // add a stuff to the repository
        ObjectConnection con = repository.getConnection();
        ValueFactory vf = con.getValueFactory();

        Inner inner = new Inner("some inner data");
        URI innerId = vf.createURI("http://example.com/inners/inner1");
        con.addObject(innerId, inner);

        URI outerId = vf.createURI("http://example.com/outers/outer1");
        Outer outer = new Outer("some outer data");
        outer.setInnerObject(inner);
        con.addObject(outerId, outer);

        // look at the triples that were created
        System.out.println("\n\n\nGenerated triples:");
        RDFWriter writer = Rio.createWriter(RDFFormat.NTRIPLES, System.out);
        con.prepareGraphQuery(QueryLanguage.SPARQL, "CONSTRUCT { ?s ?p ?o } WHERE {?s ?p ?o }").evaluate(writer);

        // close everything down
        con.close();
        repository.shutDown();
    }
}

输出:

我只创建了两个对象实例,并将它们分开保存。阿里巴巴似乎忽视了这一点,并创建了内部实例的第二份副本作为b节点,以供外部实例的引用。

代码语言:javascript
复制
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/C:/Users/me/.gradle/caches/modules-2/files-2.1/org.slf4j/slf4j-jdk14/1.7.7/25d160723ea37a6cb84e87cd70773ff02997e857/slf4j-jdk14-1.7.7.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/Users/me/.gradle/caches/modules-2/files-2.1/org.slf4j/slf4j-log4j12/1.7.12/485f77901840cf4e8bf852f2abb9b723eb8ec29/slf4j-log4j12-1.7.12.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.JDK14LoggerFactory]
Jan 08, 2016 6:00:21 PM org.openrdf.repository.object.managers.helpers.Scanner scan
INFO: Scanning C:\workspace\AlibabaTest\bin for concepts
Jan 08, 2016 6:00:22 PM org.openrdf.repository.object.ObjectRepository compileSchema
INFO: Compiling schema
Jan 08, 2016 6:00:22 PM org.openrdf.repository.object.composition.ClassResolver setBaseClassRoles
WARNING: Concept will only be mergable: class alibabaeval.domain.Inner
Jan 08, 2016 6:00:22 PM org.openrdf.repository.object.composition.ClassResolver setBaseClassRoles
WARNING: Concept will only be mergable: class alibabaeval.domain.Outer



Generated triples:
<http://example.com/inners/inner1> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.com/innerType> .
<http://example.com/inners/inner1> <http://example.com/innerType/data> "some inner data" .
<http://example.com/outers/outer1> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.com/outerType> .
_:node1a8hqu4aqx1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.com/innerType> .
_:node1a8hqu4aqx1 <http://example.com/innerType/data> "some inner data" .
<http://example.com/outers/outer1> <http://example.com/outerType/innerObject> _:node1a8hqu4aqx1 .
<http://example.com/outers/outer1> <http://example.com/outerType/data> "some outer data" .
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-01-11 22:24:56

问题是Inner的id被添加到商店中,但是实际的Inner POJO没有被更新。要解决这个问题,只需在调用inner = con.getObject(Inner.class, innerId);之后添加一行addObject

FWIW额外的往返惩罚并不像阿里巴巴最近所做的那样特别严重--访问对象缓存--因此它不需要一直到持久化层进行查找。

至于如何从对象本身获取标识资源:如果确保POJO实现了RDFObject接口,则可以调用getResource检索相关的id。顺便说一句,getResource方法的实现可以简单地返回null,因为阿里巴巴将覆盖其生成的对象中的实现。

票数 0
EN

Stack Overflow用户

发布于 2016-01-13 23:19:06

现在我对阿里巴巴更加熟悉了,在再看了一遍文件之后,我看到了一个更好的答案。

阿里巴巴将在一个分离的对象上使用RDFObject.getResource()返回的值。下面是一个内部实现,它实现了这样的功能:

代码语言:javascript
复制
package alibabaeval.domain;

import org.openrdf.annotations.Iri;
import org.openrdf.model.Resource;
import org.openrdf.model.impl.URIImpl;
import org.openrdf.repository.object.ObjectConnection;
import org.openrdf.repository.object.RDFObject;

@Iri("http://example.com/#innerType")
public class Inner implements RDFObject {

    @Iri("http://example.com/innerType/data")
    private String data;

    private Resource detachedId;

    public Inner() {

    }

    @Override
    public ObjectConnection getObjectConnection() {
        // don't really care about this one right now
        return null;
    }

    @Override
    public Resource getResource() {
        // only run on detached object, is hidden by a proxy on managed objects
        return detachedId;
    }

    public Resource getDetachedId() {
        return detachedId;
    }

    public void setDetachedId(Resource detachedId) {
        this.detachedId = detachedId;
    }

    public void setDetachedId(String detachedId) {
        this.detachedId = new URIImpl(detachedId);
    }

    public void setResource(Resource resource) {
        detachedId = resource;
    }

    public Inner(String data) {
        this.data = data;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }
}

这允许您这样做:

代码语言:javascript
复制
    Inner inner = new Inner("some inner data");
    inner.setDetachedId("http://example.com/inners/inner1");

    URI outerId = vf.createURI("http://example.com/outers/outer1");
    Outer outer = new Outer("some outer data");
    outer.setInnerObject(inner);
    con.addObject(outerId, outer);

得到这些三元组:

代码语言:javascript
复制
<http://example.com/inners/inner1> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.com/#innerType> .
<http://example.com/inners/inner1> <http://example.com/innerType/data> "some inner data" .
<http://example.com/outers/outer1> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.com/#outerType> .
<http://example.com/outers/outer1> <http://example.com/outerType/data> "some outer data" .
<http://example.com/outers/outer1> <http://example.com/outerType/innerObject> <http://example.com/inners/inner1> .

这种技术也适用于单参数ObjectConnection.addObject(Object instance)方法。

这也只适用于分离的对象。阿里巴巴管理的实例将代理RDFObject.getResource()方法,因此您不再控制它返回的内容。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34688155

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档