OrientDB 3.0.4 Java OValidationException:该字段已声明为EMBEDDEDLIST,但使用了不兼容的类型

时间:2018-07-12 18:43:42

标签: java orientdb embeddedlist

我正在使用OrientDB版本3.0.4 Java和orientdb-client.3.0.4 Java驱动程序/库。

我正尝试使用EMBEDDEDLIST类型,如下所示:

数据库架构:

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

使用OrientDB控制台,可以进行以下工作:

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}]|
+----+------+-------+-----+-------------------------------------+

使用Java失败:

尝试创建具有两个作为列表(ArrayList)存储的Phone对象的Profile Vertex时,代码失败,但出现以下异常:

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)

代码如下:

    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();
    }

以下是输出:

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)

以下是Java类:


    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()) +
                    '}';
        }
    }



解决方案:

我解决了以下问题:

    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();
    }

根据位于以下位置的文档,我不清楚什么 https://orientdb.com/docs/last/general/Types.html代表EMBEDDEDLIST 应该是Java类型 List ,但是我不得不使用 List

文档指出“记录包含在所有者内部。包含的记录没有记录ID,并且只能通过浏览所有者记录才能访问”,但是在这种情况下,按以下方式创建了电话顶点:


    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   |
    +----+-----+------+------+

以下位置的文档似乎很少,并且没有提供EMBEDDEDLIST的示例。

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

我想知道是否有人可以指向更好的文档,以便使用Java API与OrientDB或任何GraphDB进行交互。

0 个答案:

没有答案