I am using OrientDB version 3.0.4 with Java and orientdb-client.3.0.4 Java driver/library.

I am trying to use EMBEDDEDLIST type as follows:

DB schema:

create class Phone EXTENDS V

create property Phone.number String

create class Profile EXTENDS V

create property Profile.name String

create property Profile.phone embeddedList Phone

Using OrientDB console, following works:

CREATE VERTEX Profile SET name = "User1", phone = [{ "number" : "914" }, { "number" : "212" }]


     SELECT * From Profile where name="User1"               

+----+------+-------+-----+-------------------------------------+
|#   |@RID  |@CLASS |name |phone                                |
+----+------+-------+-----+-------------------------------------+
|0   |#198:2|Profile|User1|[Phone{number:914},Phone{number:212}]|
+----+------+-------+-----+-------------------------------------+

Using Java It fails:

While trying to create the Profile Vertex having two Phone(s) objects stored as List (ArrayList), code fails with following exception:

com.orientechnologies.orient.core.exception.OValidationException: The field 'Profile.phone' has been declared as EMBEDDEDLIST but an incompatible type is used. Value: Phone{number:212}
    DB name="test"
    Error Code="4"
    at com.orientechnologies.orient.core.record.impl.ODocument.validateEmbedded(ODocument.java:814)

Here is the code:

    public void insertProfileTest() throws JsonProcessingException {
        LOGGER.info(dbSession.getMetadata().getSchema().getClass(Profile.class).getProperty("name").toString());
        LOGGER.info(dbSession.getMetadata().getSchema().getClass(Profile.class).getProperty("phone").toString());
        LOGGER.info(dbSession.getMetadata().getSchema().getClass(Phone.class).getProperty("number").toString());

        // Init
        Profile userProfile = new Profile("Jane Doe");
        Phone homePhone = new Phone("212");
        Phone cellPhone = new Phone("718");
        userProfile.addPhone(homePhone);
        userProfile.addPhone(cellPhone);
        final String json = MAPPER.writeValueAsString(userProfile);
        LOGGER.info("Profile JSON:" + json);
        LOGGER.info("Phone Class :" + userProfile.getPhone().getClass().getName());

        // DB
        final OVertex profileVertex = dbSession.newVertex("Profile");
        profileVertex.setProperty("name", userProfile.getName());
        profileVertex.setProperty("phone", userProfile.getPhone(), OType.EMBEDDEDLIST);

        // Fails to Save -
        // The field 'Profile.phone' has been declared as EMBEDDEDLIST but an incompatible type is used. Value: com.sample.profile.Phone@32f232a5
        profileVertex.save();
    }

Here is the output:

14:11:00.124 [main] INFO com.sample.profile.ProfileTest - Initializing begin
14:11:01.187 [main] INFO com.sample.profile.ProfileTest - OrientDB [remote:localhost/test] Status: [OPEN]
14:11:01.191 [main] INFO com.sample.profile.ProfileTest - name (type=STRING)
14:11:01.192 [main] INFO com.sample.profile.ProfileTest - phone (type=EMBEDDEDLIST)
14:11:01.192 [main] INFO com.sample.profile.ProfileTest - number (type=STRING)
14:11:01.233 [main] INFO com.sample.profile.ProfileTest - Profile JSON:{"name":"Jane Doe1","phone":[{"number":"212"},{"number":"718"}]}
14:11:01.234 [main] INFO com.sample.profile.ProfileTest - Phone Class :java.util.ArrayList

Jul 12, 2018 2:11:01 PM com.orientechnologies.common.log.OLogManager log
INFO: Orient Engine is shutting down...

com.orientechnologies.orient.core.exception.OValidationException: The field 'Profile.phone' has been declared as EMBEDDEDLIST but an incompatible type is used. Value: Phone{number:212}
    DB name="test"
    Error Code="4"

    at com.orientechnologies.orient.core.record.impl.ODocument.validateEmbedded(ODocument.java:814)
    at com.orientechnologies.orient.core.record.impl.ODocument.validateField(ODocument.java:601)
    at com.orientechnologies.orient.core.record.impl.ODocument.validate(ODocument.java:2365)
    at com.orientechnologies.orient.core.db.document.ODatabaseDocumentAbstract.saveInternal(ODatabaseDocumentAbstract.java:2057)
    at com.orientechnologies.orient.core.db.document.ODatabaseDocumentAbstract.save(ODatabaseDocumentAbstract.java:2042)
    at com.orientechnologies.orient.core.db.document.ODatabaseDocumentAbstract.save(ODatabaseDocumentAbstract.java:84)
    at com.orientechnologies.orient.core.record.impl.ODocument.save(ODocument.java:2109)
    at com.orientechnologies.orient.core.record.impl.ODocument.save(ODocument.java:2100)
    at com.orientechnologies.orient.core.record.impl.ODocument.save(ODocument.java:63)
    at com.sample.profile.ProfileTest.insertProfileTest(ProfileTest.java:98)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

Here are the Java classes:


    package com.sample.profile;

    public class Phone  {
        private String number;

        public Phone() {
        }

        public Phone(String number) {
            this.number = number;
        }

        public String getNumber() {
            return number;
        }

        public void setNumber(String number) {
            this.number = number;
        }

        @Override
        public String toString() {
            return "Phone{" +
                    "number:" + number +
                    '}';

        }
    }


    package com.sample.profile;

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Collection;

    public class Profile {

        private String name;
        private Collection phone;

        public Profile() {
        }

        public Profile(String name) {
            this.name = name;
        }

        public Profile(String name, Collection phone) {
            this.name = name;
            this.phone = phone;
        }

        public void addPhone(Phone phoneNumber)
        {
            if (this.phone == null) {
                this.phone = new ArrayList();
            }
            this.phone.add(phoneNumber);
        }
        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Collection getPhone() {
            return phone;
        }

        public void setPhone(Collection phone) {
            this.phone = phone;
        }

        @Override
        public String toString() {
            return "Profile{" +
                    "name='" + name + '\'' +
                    ", phone=" + Arrays.toString(phone.toArray()) +
                    '}';
        }
    }



Solution:

I resolved the issue as follows:

    public void insertProfileTest() throws JsonProcessingException {
        LOGGER.info(dbSession.getMetadata().getSchema().getClass(Profile.class).getProperty("name").toString());
        LOGGER.info(dbSession.getMetadata().getSchema().getClass(Profile.class).getProperty("phone").toString());
        LOGGER.info(dbSession.getMetadata().getSchema().getClass(Phone.class).getProperty("number").toString());

        // Init
        Profile userProfile = new Profile("Jane Doe");
        Phone homePhone = new Phone("212");
        Phone cellPhone = new Phone("718");
        userProfile.addPhone(homePhone);
        userProfile.addPhone(cellPhone);
        final String json = MAPPER.writeValueAsString(userProfile);
        LOGGER.info("Profile JSON:" + json);
        LOGGER.info("Phone Class :" + userProfile.getPhone().getClass().getName());

        // DB
        List phoneVertexList = new ArrayList();
        for (Phone phone: userProfile.getPhone()) {
            final OVertex phoneVertex = dbSession.newVertex("Phone");
            phoneVertex.setProperty("number", phone.getNumber());
            phoneVertexList.add(phoneVertex);
        }

        final OVertex profileVertex = dbSession.newVertex("Profile");
        profileVertex.setProperty("name", userProfile.getName());
        profileVertex.setProperty("phone", phoneVertexList, OType.EMBEDDEDLIST);

        profileVertex.save();
    }

What is not clear to me as per the documentation at https://orientdb.com/docs/last/general/Types.html for the EMBEDDEDLIST that it should be of Java type List<Object> but I had to use List<OVertex> .

The documentation states "The Records are contained inside the owner. The contained records have no Record ID's and are reachable only by navigating the owner record" but then in this case Phone vertexes were created as follows:


    select * from Profile

    +----+-----+-------+--------+-------------------------------------+
    |#   |@RID |@CLASS |name    |phone                                |
    +----+-----+-------+--------+-------------------------------------+
    |0   |#41:0|Profile|Jane Doe|[Phone{number:212},Phone{number:718}]|
    +----+-----+-------+--------+-------------------------------------+

    select * from Phone

    +----+-----+------+------+
    |#   |@RID |@CLASS|number|
    +----+-----+------+------+
    |0   |#33:0|Phone |212   |
    |1   |#34:0|Phone |718   |
    +----+-----+------+------+

The documentation at following locations seems very minimal and do not provide example of EMBEDDEDLIST.

https://orientdb.com/docs/last/java/Java-Query-API.html https://tinkerpop.apache.org/docs/current/reference/#connecting-via-java

I am wondering if anyone can point to better documentation for use of Java API to interact with OrientDB or any GraphDB.

0

There are 0 best solutions below