I have a UML class Student
that has an attribute id
. I want to write a query in OCL to find a particular Student
by only knowing its id
. Should I use allInstances()
? Or derive? I'm not very familiar with OCL.

- 68,716
- 7
- 72
- 138

- 83
- 1
- 5
-
OCL is not meant to _find_ an object but to express constraints. – qwerty_so Jul 31 '22 at 19:15
-
3The "C" in OCL is a misnomier. OCL is an Expression Language. It may express operation bodies and property initializers in addition to constraints. – Ed Willink Aug 01 '22 at 04:50
-
@EdWillink One never stops learning. Thanks! – qwerty_so Aug 01 '22 at 08:20
-
@EdWillink I agree. Don’t hesitate to upvote the question to show that it’s relevant and interesting ;-) – Christophe Aug 01 '22 at 09:01
2 Answers
Usually OCL is used to express some constraints on an UML model, in relation to a given class instance (context
or self
) and you’ll start navigating from a specific instance.
But OCL was developed as a formal specification language that can be used to specify more than only constraints, and in particular queries as explained in section 7.1. of the OCL specifications.
If you want to express something regarding all the possible instances of a class MyClass
, you would then start your clause with:
MyClass.allInstances()
Wich is a set containing all the instances of the given class. Typically, you would then operate on this set to further specify some model features.
For example, to express uniqueness of an id, you would write a Boolean clause on this set (based on example of section 7.5.10 of the OCL specs)
MyClass.allInstances()->forAll(e1, e2 | e1 <> e2 implies e1.id <> e2.id)
One of the operation you can perform on such set is to create a subset by selecting elements that match a certain condition, and this should answer your question:
MyClass.allInstances()->select(c|c.id='...')
Additional thoughts:
OCL is an abstract language. Nothing is said on how this expression will be implemented. It could be a large inefficient iteration over an in-memory collection, or a very effective SQL query. OCL will help you to define what the result should be, but not how to really get it. So performance should not be your concern at this level of abstraction.
Now, you didn’t tell the purpose of your OCL query. If it is to explain how database queries will be performed, you could see some advantages in separation of concerns: identify the relevant classes and reusable queries and enrich your model using the repository pattern: a repository is a (singleton) class MyClassRepository
that acts as a container of all objects of a given MyClass
in the database. You would then define operation for manipulating and querying the database. Typically, you’ll have a couple of getXxxx()
operation like getById()
that return one or a set of several instances. First it will make explicit what is to be implemented as a database functionality, second the new operations can be used to simplify some OCL expressions.

- 732,580
- 175
- 1,330
- 1,459

- 68,716
- 7
- 72
- 138
-
@EdWillink indeed, I corrected the typo in the first expression. Thanks for pointing it out :-) – Christophe Aug 01 '22 at 08:56
-
Yes. Performance shouldn't be a concern, but... IIRC it was Dan Chiorean who pointed out to me how dreadful the 7.5.10 example is. The performance is quartic since "context Person". The constraint is evaluated for each person (one), invoking a model search (two), and performing a 2d iteration (three, four). Use of a more relevant context like a Company can avoid the search, and avoid the stupid evaluate everywhere and also support allowing multiple companies to maintain their own id-allocators. It is not that long ago that Eclipse OCL cached allInstances() to avoid multiple model searches... – Ed Willink Aug 01 '22 at 14:31
-
... Other tools may be less optimized. Use of isUnique() may well find an underlying implementation that uses a map to avoid the 2 dimensions. So moving to isUnique within a sensible context can change quartic to nearly linear. IMHO today there is nearly always a (much) better solution than allInstances(). Tomorrow https://bugs.eclipse.org/bugs/show_bug.cgi?id=571557 summarizes my ideas for Package Constraints and/or their automation as self-less constraints. – Ed Willink Aug 01 '22 at 14:32
Yes. allInstances() is the easy solution, but potentially the least efficient and not necessarily flexible.
If your application and constraints (for one School) are expanded to multiple schools you may realize that actually you wanted the Student at a particular School, so it is often better to go to the logical context and invoke a method on the School to return a given Student. Perhaps this is what you meant by 'derive'. The implementation of School.students->at(id) might well use a Map giving multiple gains, through not searching the whole model for every access and through having a fast access to what you have already got.

- 1,205
- 7
- 8