I'm new to OrientDB and I just started to experiment with its GUI. Now I encountered a non-intuitive behavior and I'm not sure whether it is a bug or it is only my limited understanding.
In the initial setup, OrientDB had a vertex "V". I am able to create new vertices in the graph editor:
(+) Add vertex: Select "V"
However, if I rename the vertex "V" or create another vertex ("EAN-Key"), it is not possible to select it. The only option in the dialog is "V" (or nothing if I rename "V" in the Schema Manager of the GUI and rebuild all indexes).
In the logs, I see this error message:
2015-08-20 15:40:05:713 SEVERE Internal server error:d request: sql.hjava.lang.IllegalArgumentException: Class 'EAN-Key' is not an instance of V [ONetworkProtocolHttpDb]
Is there something special about "V"? I cannot see any difference in the "Schema Manager". I did not find any information in the documentation, too.
"V" is the base class for vertices. This is a convention. If you want to create your own Vertex Types, just create a class that extends "V". The same is for edges where the name is "E".
Related
I'm creating a very simple class diagram using the Eclipse Papyrus but I'm not able to represent instances correctly.
First of all, I'm using the SysML 1.6 profile, so my classes are actually represented in a Block Diagram instead of classes, but I believe that this does not change anything in my problem.
After creating a simple class/block in my block definition diagram (bdd) I defined some attributes for my block like the example below:
When I tried to create some instances of my block ("parts" in SysML naming convention) using an "Instance Specification" I'm not able to inherit these attributes and fill them with actual information like the "name" and "quantity" in this example.
It's possible to see that my classifier is correctly set as "My component".
The Papyrus documentation for the Object diagram is clear and says that these Instance Specification should include my attributes so I don't know what I'm doing wrong.
I've tried since now:
Create instances in the same block diagram (bdd);
Create instances in another dedicated diagram of the type internal block definition (ibd);
Use the Papyrus context menu to show/hide all my compartments. Any of them works to show my attributes.
Apparently, the same problem occurs without any SysML profile and using pure UML like this question here (from 2016!!)
Papyrus version: 6.1.0
From the diagram on page 570 of the UML spec I concluded that a Lifeline should have the events property, holding an OrderedSet(OcurrenceSpecification). Unfortunately it is not there, at least in the QVTo implementation that I use.
All I have is the coveredBy property, serving me with an (unordered) Set(InteractionFragment). Since my transformation relies on the correct order of MessageOcurrenceSpecification I somehow need to implement myself what I expected to be implemented by the missing events property.
This is what I have so far:
helper Lifeline::getEvents (): OrderedSet(OccurrenceSpecification) {
return self.coveredBy->selectByKind(OccurrenceSpecification)->sortedBy(true);
}
Obviously sortedBy(true) does not get me far, but I don't know any further. Who can help?
All I could find so far were other people struggling with the same issue years ago, but no solution:
https://www.eclipse.org/forums/index.php/m/1049555/
https://www.eclipse.org/forums/index.php/m/1050025/
https://www.eclipse.org/forums/index.php/m/1095764/
Based on the answer by Vincent combined with input from a colleague of mine I came up with the following solution for QVTo:
-- -----------------------------------------------------------------------------
-- Polyfill for the missing Lifeline::events property
query Lifeline::getEvents (): OrderedSet(OccurrenceSpecification) {
return self.interaction.fragment
->selectByKind(OccurrenceSpecification)
->select(os: OccurrenceSpecification | os.covered->includes(self))
->asOrderedSet();
}
I don't know if it is possible, using directly coveredBy to get an ordered collection. As coveredBy is unordered, if you access it directly by the feature, you will have an unpredictible order and if you try to access it using the eGet(...) stuff, the same result will occur.
However, if I understood correctly, there is a "trick" that could work.
It relies on the assumption that each OccurrenceSpecification instance you need is held by the same Interaction that contains the Lifeline and uses the way EMF stores contained elements. Actually, each contained element is always kind of 'ordered' relatively to its parent (and for each collection so EMF can find elements back when XMI references are expressed using the element position in collections). So, the idea would be to access all the elements contained by the Interaction that owns the lifeline and filter the ones that are contained in coveredBy.
Expression with Acceleo
This is easy to write in MTL/Acceleo. In know you don't use it, but it illustrates what the expression does:
# In Acceleo:
# 'self' is the lifeline instance
self.interaction.eAllContents(OccurrenceSpecification)->select(e | self.coveredBy->includes(e))->asOrderedSet()
with self.interaction we retrieve the Interaction, then we get all the contained elements with eAllContents(...) and we filter the ones that are in the self.coveredBy collection.
But it is way less intuitive in QVT as eAllContents(...) does not exist. Instead you have to gain access to eContents() which is defined on EObject and returns an EList which is transtyped to a Sequence (in QVT,eAllContents() returns a ETreeIterator which is not transtyped by the QVT engine).
So, how to gain access to eContents() in the helper? There is two solutions:
Solution 1: Using the emf.tools library
The emf.tools library give you the ability to use asEObject() which casts your object in a pure EObject and give you more methods to access to (as eClass() for example...etc).
import emf.tools; -- we import the EMF tools library
modeltype UML ...; -- all your metamodel imports and stuffs
...
helper Lifeline::getEvents (): OrderedSet(OccurrenceSpecification) {
return self.interaction.asEObject().eContents()[OccurrenceSpecification]->select(e | self.coveredBy->includes(e))->asOrderedSet();
}
Solution 2: Using oclAstype(...)
If for some reason emf.tools cannot be accessed, you can still cast to an EObject using oclAsType(...).
modeltype UML ...; -- all your metamodel imports and stuffs
modeltype ECORE "strict" uses ecore('http://www.eclipse.org/emf/2002/Ecore'); -- you also register the Ecore metamodel
...
helper Lifeline::getEvents (): OrderedSet(OccurrenceSpecification) {
return self.interaction.oclAsType(EObject).eContents()[OccurrenceSpecification]->select(e | self.coveredBy->includes(e))->asOrderedSet();
}
Limitation
Ok, let's be honest here, this solution seems to work on the quick tests I performed, but I'm not a 100% sure that you will have all the elements you want as this code relies on the strong assumption that every OccurrenceSpecification you need are in the same Interaction as the Liteline instance. If you are sure that all the coveredBy elements you need are in the Interaction (I think they should be), then, that's not the sexiest solution, but it should do the work.
EDIT>
The solution proposed by hielsnoppe is more eleguant than the one I presented here and should be prefered.
You are correct. The Lifeline::events property is clearly shown on the diagram and appears in derived models such as UML.merged.uml.
Unfortunately Eclipse QVTo uses the Ecore projection of the UML metamodel to UML.ecore where unnavigable opposites are pruned. (A recent UML2Ecore enhancement allows the name to be persisted as an EAnnotation.) However once the true property name "events" has been pruned the implicit property name "OccurrenceSpecification" should work.
All associations are navigable in both directions in OCL, so this loss is a bug. (The new Pivot-based Eclipse OCL goes back to the primary UML model in order to avoid UML2Ecore losses. Once Eclipse QVTo migrates to the Pivot OCL you should see the behavior you expected.)
I wish to extract all the edges and vertices that are attached to a specific list and who they follow and copy them to either neo4j directly or by creating a graphson or a kryo file of the data.
Something similar to this:
g.V().has("sublist_id", 14).in('ON').out('FOLLOWS')
I basically want every vertices and edge in a separate database or file to query in isolation.
What is my best approach approach?
I did the following but can't seem to export as json or kryo only graphml.
gremlin> subGraph = g.V().has('sublist_id', 14).in('ON').outE('FOLLOWS').subgraph('subGraph').cap('subGraph').next()
==>tinkergraph[vertices:3438716 edges:14090945]
gremlin> subGraph.io(IoCore.gryo()).writeGraph("/data/test.kryo")
Class is not registered: com.thinkaurelius.titan.graphdb.relations.RelationIdentifier
Note: To register this class use: kryo.register(com.thinkaurelius.titan.graphdb.relations.RelationIdentifier.class);
Display stack trace?
gremlin> subGraph.io(IoCore.graphson()).writeGraph("/data/test.json");
(was java.lang.IllegalStateException) (through reference chain: com.thinkaurelius.titan.graphdb.relations.RelationIdentifier["inVertexId"])
Display stack trace? [yN]
When you generate a subgraph from one graph and try to push to another you might end up with serialization problems because the new graph might not know how to deal with the data within the first graph. That is the case you are having here, specifically with the RelationIdentifier which is the unique id in Titan.
So to state that in the context of your work, you have a TinkerGraph that has Titan RelationIdentifier in it and when you go to write that to gryo, the serialization process fails because TinkerGraph doesn't have knowledge of the Titan serializers.
You can work around this problem by giving gryo the Titan serializers. Do something like:
gryo = GryoIo.build().registry(TitanIoRegistry.INSTANCE).graph(subGraph).create()
gryo.writeGraph("/data/test.kryo")
That's one way to do it. You could also build the GryoWriter up from scratch for even more control over different options and settings.
In Enterprise Architect (EA) 9.3 I do the following on a UML class diagram:
Select an Association link between two classes
Right-click and choose Advanced / Change Type from context menu
Change type from Association to Aggregation and click OK
What I find is that the diamond symbol for an aggregation is drawn on the wrong side (the destination side).
Is this a known bug? Is there a easy workaround? Thanks.
In enterprise architect the lines are drawn from part to whole, so source is without the diamond.
If you want to change it:
Go to Tools-> Options -> Links
And set the "Draw Aggregations Reversed" Option
Don't change an Association to an Aggregation. Instead, open the Association's properties and go to either the Source Role or Target Role page and set the "Aggregation" value to "shared" or "composite".
I have thrown together a small Lift application, using CRUDify, to perform basic CRUD operations on some database tables.
Several columns are of type "CHAR (1 byte)", and are intended to store values of "Y" or "N". My model class defines those fields like this example:
...
object isActive extends MappedEnum(this, YesNo) {
override def dbColumnName = "IS_ACTIVE"
override def displayName = "Active"
}
...
That type, "YesNo" is a Scala object defined as follows:
object YesNo extends Enumeration {
val Y, N = Value
}
In the web browser forms that are auto-generated by CRUDify, columns such as this do show up with "Y" and "N" as the available options. However, when you create or edit a row... what actually gets stored is "1" or "0"!
Clearly, I'm just missing the boat on something here. How can I structure this such that CRUDify will allow users to select from "Y" or "N" in the browser, and store either "Y" or "N" in the database?
Hmm... not a huge Scala / Lift community here on StackOverflow! Actually, it may be that there isn't much of a community for this "CRUDify" sub-component of Lift anywhere.
At any rate, I eventually found an answer (sorta) by subscribing to the "liftweb" Google Groups mailing list. Apparently, this is a known limitation in the CRUDify framework. It's been like that for years and is not a limitation that anyone particularly cares about, but it is known.
One developer back in 2009 tried to find a way around this by creating his own custom subclass of MappedField, and using that as the mapped type in his Lift model classes. The 140-line class, along with an email briefly describing it, may be found at:
http://groups.google.com/group/liftweb/browse_frm/thread/34560f30fab299a7/cdca54c8e1486237?pli=1
I am not sure that this worked 100% back in 2009, and it has a ton of problems when I tried to use it here in 2012 (Scala and Lift have both changed a lot over the past three years).
I invested a small amount of time into trying to make this MappedField subclass work... and then received approval to choose an approach other than CRUDify. Part of the mission for this little app was to learn some things about what to do and what not to do with Lift, and I think we've accomplished that part of the mission now. :)
However, if this research and sample code helps out someone else down the line later, then that would be great.