Jena tip: using resources from different models

This question has been asked on the Jena support list a few times recently, so I guess it would be handy to have an answer that Google can find easily.

I have a quick question regarding the use of constant Property and Resource objects. If I use schemagen to generate constants, is it then safe to use a Property (like petName) created from m_model in a model that is created somewhere else? I guess this isn’t really a schemagen question as much as a general Jena question: Is it safe to create a Property/Resource in one model, and then use them to query a different model (obviously conforming to the same ontology)?

Answer: yes, it’s perfectly safe provided you understand what’s going on (so that you don’t get unexpected results).

The trick is to realise that each resource (and property, since properties are resources) has a model to which it belongs. This may be null. If you call a method on a resource to add a value to that resource, the statement that is created will be created in the resource’s model. The only reason that resources have model pointers is to allow this style of convenience programming. So for example, you can have:

Resource r = m1.createResource();
r.addProperty( foo, "bar" )
 .addProperty( fu, "baz" );

Which will add two statements with r as subject to model m1. That’s the convenience of the convenience API. There’s no reason why you can’t do:

m2.add( r, foo, bar );

even if r, foo and bar are defined in different models than m2. In particular, if you do the following:

m2.add( r, foo, bar )
  .getSubject()
  .getModel()

you’ll get m2 as a result, independently of which model r was defined in.

You may also want to note that Jena’s contract for resource equality is that two resources are .equals() if they have the same URI or the same bNode identifier. The models to which they are bound are not part of the equality contract.

 newer · index · older