How do I add a linked document to a linked list using the Java API for OrientDB? - orientdb

I have an OType.LINKLIST field children in a class.
I can use the following command to update it:
update <parent_rid> add children = <child_rid>
But I don't know how to do this without using SQL, which is my goal.
code
ODocument doc=new ODocument("ClassA");
ODocument parentDoc=db.load(new ORecordId(rid));
How do I add doc to parentDoc's field children without using SQL?

create class Doc
create class ParentDoc
create property ParentDoc.children LINKLIST
insert into Doc set name = 'doc1' #12:0
insert into Doc set name = 'doc2' #12:1
insert into ParentDoc set name = 'pd', children = [#12:0] #13:0
update #13:0 add children = #12:1
For what I understood you want a piece of code that replaces the last four commands using Java Document API.
try (ODatabaseDocument db = new ODatabaseDocumentTx("remote:localhost/DB")) {
db.open("admin", "admin");
ODocument doc1 = new ODocument("Doc");
doc1.field("name", "doc1");
doc1.save();
List<OIdentifiable> linklist = new ArrayList();
linklist.add(doc1);
ODocument parent = new ODocument("ParentDoc");
parent.field("children", linklist, OType.LINKLIST);
parent.save();
// ...
ODocument doc2 = new ODocument("Doc");
doc2.field("name", "doc2");
doc2.save();
List children = parent.field("children");
children.add(doc2);
parent.field("children", children);
parent.save();
}

Related

OrientDB - exception when I try to save an embeddedlist

I have a class named CalculationFunctionGroup where I have an attribute like this:
List<CalculationFunction> functions;
on my OrientDB I have a table named CalculationFunctionGroup with a property functions definaed as EMBEDDEDLIST and linked class CalculationFunction.
When I try to save an object of type CalculationFunctionGroup an exception raises.
The exception tell me:
The field 'functions' has been declared as EMBEDDEDLIST with linked class 'CalculationFunction' but the record has no class.
I try to find this exception in OrientDB source code, and I find this:
There's a check in ODocument class in the method validateEmbedded where there are these code lines:
if (doc.getImmutableSchemaClass() == null)
throw new OValidationException("The field '" + p.getFullName() + "' has been declared as " + p.getType()
+ " with linked class '" + embeddedClass + "' but the record has no class");
So, I don't understand how can I valued the immutableschemaclass property.
Where I try to set my field value from Java, I use this command line:
this.data.field(fieldName, value, OType.EMBEDDEDLIST);
where data is my ODocument instance, fieldName is functions, value is my List of CalculationFunction and OType is EMBEDDEDLIST.
Used Orient version is 2.2.0
EDIT #1
I try this after Alessandro Rota answer, but the error is the same:
ODocument myEntity = new ODocument("CalculationFunctionGroup");
myEntity.field("referenceItem", object.getReferenceItem().getData());
db.save(myEntity);
db.commit();
In this code snippet I've changed the nature of my objct (the original is a typied object as CalculationFunctionGroup and now is an ODocument). But the error is the same.
Another try I've done, the ODocument myEntity has not attached functions (list of CalculationFunction) but the error raises too
EDIT #2
I've tried with code snippet of Alessandro Rota and works fine.
But when I add as field of CalculationFunction a link field I've the same error! Why?
If I add a link field instead of object.getData() with object.getRawField("#rid") it works fine too.
I don't understand because raises that error message, and the reason of different behaviour when I use only #rid field instead complete object
EDIT #3
Latest news:
This is my test scenario:
I have this table:
CalculationFunction with these property (schemafull):
referenceItem LINK
functions EMBEDDEDLIST
When I try to save, I write this code:
ODocument myGroup = new ODocument("CalculationFunctionGroup");
Object rid = null;
if (object.getField("referenceItem") instanceof RegistryMetadata) {
rid = ((RegistryMetadata)(object.getField("referenceItem"))).getRawField("#rid");
} else if (object.getField("referenceItem") instanceof PayrollRegistryMetadata) {
rid = ((PayrollRegistryMetadata)(object.getField("referenceItem"))).getRawField("#rid");
} else if (object.getField("referenceItem") instanceof PreCalculationMetadata) {
rid = ((PreCalculationMetadata)(object.getField("referenceItem"))).getRawField("#rid");
} else if (object.getField("referenceItem") instanceof CalculationMetadata) {
rid = ((CalculationMetadata)(object.getField("referenceItem"))).getRawField("#rid");
}
myGroup.field("referenceItem", rid, OType.LINK);
myGroup.field("scenario", ((Scenario)object.getField("scenario")).getRawField("#rid"));
List<ODocument> lstFunctions = new ArrayList<ODocument>();
if (object.getField("functions") != null) {
Iterable<ODocument> lstFun = (Iterable<ODocument>) object.getField("functions");
Iterator<ODocument> itFun = lstFun.iterator();
while(itFun.hasNext()) {
ODocument currFun = itFun.next();
ODocument oFun = new ODocument("CalculationFunction");
oFun.field("name", currFun.field("name"));
oFun.field("code", currFun.field("code"));
oFun.field("language", currFun.field("language"));
lstFunctions.add(oFun);
}
}
myGroup.field("functions", lstFunctions, OType.EMBEDDEDLIST);
myGroup.save();
db.commit();
This code goes in error, but... If I write this:
myGroup.field("referenceItem2", rid, OType.LINK);
The code works fine.
The difference: referenceItem is a schemafull property, referenceItem2 is a schemaless field.
You could use this code
ODocument cf1= new ODocument("CalculationFunction");
cf1.field("name","Function 1",OType.STRING);
ODocument cf2= new ODocument("CalculationFunction");
cf2.field("name","Function 2",OType.STRING);
List<ODocument> list=new ArrayList<ODocument>();
list.add(cf1);
list.add(cf2);
ODocument p = new ODocument("CalculationFunctionGroup");
p.field("functions", list, OType.EMBEDDEDLIST);
p.save();
Edit 2
If you want add a link you could use this code
ODocument cf1= new ODocument("CalculationFunction");
cf1.field("name","Function 1",OType.STRING);
ODocument p = new ODocument("CalculationFunctionGroup");
p.field("mylink", cf1, OType.LINK);
p.save();
EDIT 3
I have created schemafull property mylink2
I have used this code
ODocument cf1= new ODocument("CalculationFunction");
cf1.field("name","Function 1",OType.STRING);
cf1.save();
ODocument p = new ODocument("CalculationFunctionGroup");
p.field("mylink", cf1.getIdentity(), OType.LINK);
p.field("mylink2", cf1.getIdentity(), OType.LINK);
p.save();
and I got
Hope it helps.

Cascade save on OrientDB Document API when using embedded types

Given the following test:
// setup
OClass driver = getDatabase().getMetadata().getSchema().createClass(DRIVER);
OClass car = getDatabase().getMetadata().getSchema().createClass(CAR);
car.createProperty(DRIVERS, OType.EMBEDDEDLIST, driver);
OClass team = getDatabase().getMetadata().getSchema().createClass(TEAM);
team.createProperty(CARS, OType.EMBEDDEDSET, car);
// exercise
ODocument alonso = new ODocument(DRIVER).field("name", "Fernando Alonso").field("nationality", "Spanish")
.field("yearOfBirth", 1981);
ODocument button = new ODocument(DRIVER).field("name", "Jenson Button").field("nationality", "british")
.field("yearOfBirth", 1980);
ODocument mp30 = new ODocument(CAR).field(DRIVERS, Arrays.asList(new ODocument[] { alonso, button }));
Set<ODocument> cars = new HashSet<>();
cars.add(mp30);
ODocument mclarenF1Team = new ODocument(TEAM).field(CARS, cars);
mclarenF1Team.save();
// verify
assertEquals(1, getDatabase().countClass(TEAM));
assertEquals(1, getDatabase().countClass(CAR));
assertEquals(2, getDatabase().countClass(DRIVER));
The second assertion fails:
java.lang.AssertionError: expected:<1> but was:<0>
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.failNotEquals(Assert.java:834)
at org.junit.Assert.assertEquals(Assert.java:645)
at org.junit.Assert.assertEquals(Assert.java:631)
at foo.orientdb.dataaccessapi.StoreJSonIT.testSchemaFull(StoreJSonIT.java:68)
Why does it fail?
The properties CAR and DRIVER are created as embedded list and embedded set, shouldn't a single save in mclarenF1Team do a cascade save for the embedded documents?
Embedded List/Set means that the documents you create will be embedded (Saved) in the parent document and not in his own class/cluster.
IF you want to achieve that behaviour you should use links
See here
http://orientdb.com/docs/2.1/Concepts.html#relationships

Zendframework 2 postgresql update with "not"

Is is possible to pass to database the following sql query using tableGateway, if so, how would such a command look like ?
UPDATE table_data SET active = not active where table_data.id = 12;
You need to use a Zend\Db\Sql\Expression, this class tells Zend\Db that you know what you're doing and that the content of the string passed to this class shouldn't be transformed, but rather used as is.
// build the table gateway object
$adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
$tableIdentifier = new TableIdentifier('table_data', 'public');
$tableGateway = new TableGateway($tableIdentifier, $adapter);
// create the filter
$where = new \Zend\Db\Sql\Where();
$where->equalTo('id', '12');
// update table
$tableGateway->update(
['active' => new \Zend\Db\Sql\Expression('not active')],
$where
);

Manipulate Doctrine NestedSet tree

I am using NestedSet behavior with doctrine 1.2.4 with Zend framework
but i am having some difficulty when inserting a child node of already saved root node
the Doctrine documentation showed the case of creating both root + child elements on the same page
while in my case , the root is already created and saved and i need to insert a child of it
here is an example
//// reading old order info
$order = new Order();
$orderInfo = $order->read($order_id);
$oldOrder = $orderInfo->toArray();
$oldOrder = $oldOrder[0];
//// building the new order information
$renew = new Orders();
$renew->domain_id = (int) $oldOrder["domain_id"];
$renew->auth_id = (int) $oldOrder["auth_id"];
$renew->price = $oldOrder["price"];
$renew->type = (string) $oldOrder["type"];
$renew->timestamp = $oldOrder["timestamp"];
$renew->save();
//// doctrine throwing an error here complaining the $orderInfo should be an instance of Doctrine_Record while its now an instance of Doctrine_Collection
$aa = $renew->getNode()->insertAsLastChildOf($orderInfo);
i don't really know how to retrieve the order from the db and how to convert it to doctrine_record or there is other ways to manipulate this nestedset
any suggestion would be appreciated
Try this:
// This will retrieve the 'parent' record
$orderInfo = Doctrine_Core::getTable('Order')->find($order_id);
// building the new order information
$renew = new Orders();
$renew->domain_id = (int) $oldOrder["domain_id"];
$renew->auth_id = (int) $oldOrder["auth_id"];
$renew->price = $oldOrder["price"];
$renew->type = (string) $oldOrder["type"];
$renew->timestamp = $oldOrder["timestamp"];
$renew->save();
$renew->getNode()->insertAsLastChildOf($orderInfo);
That should get a Doctrine Record of the parent node and you can use that to insert the child as the last child of.

How can I insert and get PK Id using Entity Framework?

currently I'm Inserting like:
MyNamedEntities db = new MyNamedEntities();
MyTableEntity field = new MyTableEntity();
field.Name = "me";
db.MyTableEntity.AddObject(field);
db.SaveChanges()
But now I want to insert child elements and I need that field.Id part
MyOtherTableEntity field = new MyOtherTableEntity();
field.TableId = new MyTableEntity.First(x => x.Id.Equals( ... ));
How can I get the field.Id ?
If your table has defined the Id as an INT IDENTITY column, then you don't really have to do anything at all! :-)
In that case, just insert your entity and after the call to .SaveChanges(), your object should contain the new Id value:
MyTableEntity field = new MyTableEntity();
field.Name = "me";
db.MyTableEntity.AddObject(field);
db.SaveChanges();
int newID = field.Id;
You can also just add them to the parent by the association before or after the save changes
Something like this.
address a = new address();
a.city = "Detroit";
field.address.add(a);
db.SaveChanges();