Named graph support in Empire

59 views
Skip to first unread message

jeffb.thom...@gmail.com

unread,
May 13, 2016, 8:28:31 PM5/13/16
to Empire
Hi,

My team is using Empire for our ORM layer with a Stardog triple store.  We would like to store several related resources for a "document" in a named graph.  I've found the following information related to this, but it's quite old:



Our use case is very similar to the one described in the group posting: neither the NamedGraphType.Instance nor NamedGraphType.Static do what we need, we want to be able to place several resources into one of many named graphs chosen at runtime.  Outside of the @NamedGraph annotation, have any features been added to Empire to support this use case in the last five years or so?

Alternatively, what are your thoughts on how support for this named graph use case could be added to Empire?  Depending on how much effort is involved, our team may have the capacity to add the features that we want to Empire.

Thanks,
Jeff

Michael Grove

unread,
May 13, 2016, 8:34:06 PM5/13/16
to empir...@googlegroups.com
On Fri, May 13, 2016 at 6:20 PM, <jeffb.thom...@gmail.com> wrote:
Hi,

My team is using Empire for our ORM layer with a Stardog triple store.  We would like to store several related resources for a "document" in a named graph.  I've found the following information related to this, but it's quite old:



Our use case is very similar to the one described in the group posting: neither the NamedGraphType.Instance nor NamedGraphType.Static do what we need, we want to be able to place several resources into one of many named graphs chosen at runtime.  Outside of the @NamedGraph annotation, have any features been added to Empire to support this use case in the last five years or so?


No, there's nothing new on this front in Empire since that post.
 
Alternatively, what are your thoughts on how support for this named graph use case could be added to Empire?  Depending on how much effort is involved, our team may have the capacity to add the features that we want to Empire.

It would be relatively straightforward to add, the only hard part is where the hook comes from that tells Empire what the named graph is to use dynamically.

It's been on my todo list to add this to Pinto, and have a configurable annotation processor like there is in Jackson. That'd make it easier to add new annotations and modify/extend what happens for existing ones. I was hoping to do that when I switch Empire's engine out for Pinto. I don't know when I'll get to that though, so I won't complain about help.

Cheers,

Mike
 

Thanks,
Jeff

--
You received this message because you are subscribed to the Google Groups "Empire" group.
To unsubscribe from this group and stop receiving emails from it, send an email to empire-rdf+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

jeffb.thom...@gmail.com

unread,
May 16, 2016, 3:34:24 PM5/16/16
to Empire


On Friday, May 13, 2016 at 7:34:06 PM UTC-5, mhgrove wrote:


On Fri, May 13, 2016 at 6:20 PM, <jeffb.thom...@gmail.com> wrote:
Hi,

My team is using Empire for our ORM layer with a Stardog triple store.  We would like to store several related resources for a "document" in a named graph.  I've found the following information related to this, but it's quite old:



Our use case is very similar to the one described in the group posting: neither the NamedGraphType.Instance nor NamedGraphType.Static do what we need, we want to be able to place several resources into one of many named graphs chosen at runtime.  Outside of the @NamedGraph annotation, have any features been added to Empire to support this use case in the last five years or so?


No, there's nothing new on this front in Empire since that post.
 
Alternatively, what are your thoughts on how support for this named graph use case could be added to Empire?  Depending on how much effort is involved, our team may have the capacity to add the features that we want to Empire.

It would be relatively straightforward to add, the only hard part is where the hook comes from that tells Empire what the named graph is to use dynamically.

Yeah, I see that. Poking around the code, it looks like the main place where the @NamedGraph annotation data is actually consumed is EmpireUtil.getNamedGraph(...).  We could probably get dynamic named graphs by adding a new NamedGraphType strategy that uses a strategy class provided on a new annotation property to dynamically derive the name of the graph to use [e.g. @NamedGraph(type = NamedGraph.NamedGraphType.Strategy, strategy = MyCustomNamedGraphStrategy.class)].  EmpireUtil.getNamedGraph(...) would instantiate that class and call it with all the context it has (e.g. resource URI, perhaps the datasource connection).

This works for our team's dynamic use case since all the resources that compose a "document" will have the "document" URI as the first part of the path.  So our dynamic strategy would be to just truncate the resource URI to a specific point.  The existing NamedGraphType.Instance would be equivalent to a strategy that just returns the unmodified resource URI, and the NamedGraphType.Static would be equivalent to one that just returns a static value.  If someone wanted to pass in the graph name at runtime, they could use a ThreadLocal in their strategy and some static methods (which would be kludgy, but I don't really see another way right now without creating a nonstandard extension of the JPA interfaces).

What do you think?

Michael Grove

unread,
May 16, 2016, 4:37:40 PM5/16/16
to empir...@googlegroups.com
On Mon, May 16, 2016 at 3:34 PM, <jeffb.thom...@gmail.com> wrote:


On Friday, May 13, 2016 at 7:34:06 PM UTC-5, mhgrove wrote:


On Fri, May 13, 2016 at 6:20 PM, <jeffb.thom...@gmail.com> wrote:
Hi,

My team is using Empire for our ORM layer with a Stardog triple store.  We would like to store several related resources for a "document" in a named graph.  I've found the following information related to this, but it's quite old:



Our use case is very similar to the one described in the group posting: neither the NamedGraphType.Instance nor NamedGraphType.Static do what we need, we want to be able to place several resources into one of many named graphs chosen at runtime.  Outside of the @NamedGraph annotation, have any features been added to Empire to support this use case in the last five years or so?


No, there's nothing new on this front in Empire since that post.
 
Alternatively, what are your thoughts on how support for this named graph use case could be added to Empire?  Depending on how much effort is involved, our team may have the capacity to add the features that we want to Empire.

It would be relatively straightforward to add, the only hard part is where the hook comes from that tells Empire what the named graph is to use dynamically.

Yeah, I see that. Poking around the code, it looks like the main place where the @NamedGraph annotation data is actually consumed is EmpireUtil.getNamedGraph(...).  We could probably get dynamic named graphs by adding a new NamedGraphType strategy that uses a strategy class provided on a new annotation property to dynamically derive the name of the graph to use [e.g. @NamedGraph(type = NamedGraph.NamedGraphType.Strategy, strategy = MyCustomNamedGraphStrategy.class)].  EmpireUtil.getNamedGraph(...) would instantiate that class and call it with all the context it has (e.g. resource URI, perhaps the datasource connection).

Sure, that's an approach that could work. Using reflect for each round trip to create the strategy will add overhead, not sure how badly that'd be noticeable in your case. That's part of the reason why I wanted to have some configurable annotation processing, you could provide your factory for creating the IRI's in the mapper to avoid re-creating every time.

Cheers,

Mike

jeffb.thom...@gmail.com

unread,
May 17, 2016, 4:21:47 PM5/17/16
to Empire
Hi,

On a related note, does NamedGraphType.Static work, or am I doing something wrong?  I implemented SupportsNamedGraphs on StardogEmpireDataSource.  I can persist my entities to a static name graph fine, however I cannot seem to retrieve them using EntityManagerImpl.find(MyClass.class, "http://my.url"):

It looks like:
1. EntityManagerImpl.find(...): the string URI gets passed to DataSourceUtil.exists(getDataSource(), EmpireUtil.asPrimaryKey(theObj)) as theObj, 
2. DataSourceUtil.exists(...): then calls EmpireUtil.hasNamedGraphSpecified(theObj).
3. EmpireUtil.hasNamedGraphSpecified(..): since theObj is a SupportsRdfId$URIKey, not an instance of the class, the @NamedGraph annotation will never be found, so the query will never look in the specified graph.

It seems to me like the class parameter to EntityManagerImpl.find(...) should be passed down and used to get the named graph info, if no class instance is available.

- Jeff

Michael Grove

unread,
May 17, 2016, 9:12:27 PM5/17/16
to empir...@googlegroups.com
On Tue, May 17, 2016 at 4:21 PM, <jeffb.thom...@gmail.com> wrote:
Hi,

On a related note, does NamedGraphType.Static work, or am I doing something wrong?  I implemented SupportsNamedGraphs on StardogEmpireDataSource.  I can persist my entities to a static name graph fine, however I cannot seem to retrieve them using EntityManagerImpl.find(MyClass.class, "http://my.url"):

It looks like:
1. EntityManagerImpl.find(...): the string URI gets passed to DataSourceUtil.exists(getDataSource(), EmpireUtil.asPrimaryKey(theObj)) as theObj, 
2. DataSourceUtil.exists(...): then calls EmpireUtil.hasNamedGraphSpecified(theObj).
3. EmpireUtil.hasNamedGraphSpecified(..): since theObj is a SupportsRdfId$URIKey, not an instance of the class, the @NamedGraph annotation will never be found, so the query will never look in the specified graph.

It seems to me like the class parameter to EntityManagerImpl.find(...) should be passed down and used to get the named graph info, if no class instance is available

Yeah, that sounds like a bug.  Probably that initial call to DataSourceUtil.exists is incorrect, and should just pass theObj directly.

Cheers,

Mike
 
.

- Jeff

On Friday, May 13, 2016 at 7:28:31 PM UTC-5, jeffb.thom...@gmail.com wrote:
Hi,

My team is using Empire for our ORM layer with a Stardog triple store.  We would like to store several related resources for a "document" in a named graph.  I've found the following information related to this, but it's quite old:



Our use case is very similar to the one described in the group posting: neither the NamedGraphType.Instance nor NamedGraphType.Static do what we need, we want to be able to place several resources into one of many named graphs chosen at runtime.  Outside of the @NamedGraph annotation, have any features been added to Empire to support this use case in the last five years or so?

Alternatively, what are your thoughts on how support for this named graph use case could be added to Empire?  Depending on how much effort is involved, our team may have the capacity to add the features that we want to Empire.

Thanks,
Jeff

--

Conrad Leonard

unread,
Oct 11, 2016, 11:45:37 PM10/11/16
to Empire
For the record, I just hit the same issue.

Unfortunately the fix is not as simple as calling
DataSourceUtil.exists(getDataSource(), theObj)

in EntityManagerImpl.find because theObj passed into find and thence to DataSourceUtil.exists is often (as in this case) just an RdfKey or similar key-like identifier with no annotations.

The problem is that EntityManager.find does (and should) accept a broad range of types as "theObj", where for instances of naked key types the additional NamedGraph information on where to `find` them lives only in separately-supplied "theClass" parameter, while the code that actually does the finding — DataSourceUtil.exists(DataSource theDataSource, Object theObj) — expects all the info to be available in theObj instance.

More broadly EmpireUtil.hasNamedGraphSpecified(Object theObj) and EmpireUtil.getNamedGraph(Object theObj) expect that information on the instance too.


I tried a naive fix at https://github.com/mhgrove/Empire/blob/develop/core/main/src/com/clarkparsia/empire/impl/EntityManagerImpl.java#L668 creating a dummy instance of theClass with the correct key to query the db with:
SupportsRdfId.RdfKey<T> theKey = EmpireUtil.asPrimaryKey(theObj);
SupportsRdfId theProbe = EmpireUtil.asSupportsRdfId(theClass.newInstance());
theProbe.setRdfId(theKey);
if (DataSourceUtil.exists(getDataSource(), theProbe)) {
T aT = RdfGenerator.fromRdf(theClass, theKey, getDataSource());

but broke a lot of tests. Obvious problems with my approach, like if theClass is abstract or an interface.
Reply all
Reply to author
Forward
0 new messages