4

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

我正在尝试使用 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 失败:

在尝试创建将两个 Phone(s) 对象存储为 List (ArrayList) 的 Profile Vertex 时,代码失败并出现以下异常:

com.orientechnologies.orient.core.exception.OValidationException:“Profile.phone”字段已声明为 EMBEDDEDLIST,但使用了不兼容的类型。值:电话{号码:212}
    数据库名称="测试"
    错误代码="4"
    在 com.orientechnologies.orient.core.record.impl.ODocument.validateEmbedded(ODocument.java:814)

这是代码:

    公共无效 insertProfileTest() 抛出 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());

        // 在里面
        Profile userProfile = new Profile("Jane Doe");
        电话 homePhone = new Phone("212");
        手机 cellPhone = new Phone("718");
        userProfile.addPhone(homePhone);
        userProfile.addPhone(cellPhone);
        最终字符串 json = MAPPER.writeValueAsString(userProfile);
        LOGGER.info("配置文件 JSON:" + json);
        LOGGER.info("电话类别:" + userProfile.getPhone().getClass().getName());

        // D B
        最终 OVertex profileVertex = dbSession.newVertex("Profile");
        profileVertex.setProperty("名称", userProfile.getName());
        profileVertex.setProperty("电话", userProfile.getPhone(), OType.EMBEDDELIST);

        // 保存失败 -
        // 字段“Profile.phone”已声明为 EMBEDDEDLIST,但使用了不兼容的类型。值:com.sample.profile.Phone@32f232a5
        profileVertex.save();
    }

这是输出:

14:11:00.124 [main] INFO com.sample.profile.ProfileTest - 初始化开始
14:11:01.187 [main] INFO com.sample.profile.ProfileTest - OrientDB [remote:localhost/test] 状态:[OPEN]
14:11:01.191 [main] INFO com.sample.profile.ProfileTest - 名称(类型=字符串)
14:11:01.192 [main] INFO com.sample.profile.ProfileTest - 电话(类型 = EMBEDDEDLIST)
14:11:01.192 [main] INFO com.sample.profile.ProfileTest - 编号(类型=字符串)
14:11:01.233 [main] INFO com.sample.profile.ProfileTest - 配置文件 JSON:{"name":"Jane Doe1","phone":[{"number":"212"},{"number": "718"}]}
14:11:01.234 [main] INFO com.sample.profile.ProfileTest - 电话类:java.util.ArrayList

2018 年 7 月 12 日下午 2:11:01 com.orientechnologies.common.log.OLogManager 日志
信息:东方引擎正在关闭...

com.orientechnologies.orient.core.exception.OValidationException:“Profile.phone”字段已声明为 EMBEDDEDLIST,但使用了不兼容的类型。值:电话{号码:212}
    数据库名称="测试"
    错误代码="4"

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

以下是 Java 类:

    包 com.sample.profile;

    公共类电话{
        私有字符串编号;

        公共电话() {
        }

        公共电话(字符串号码){
            this.number = 数字;
        }

        公共字符串 getNumber() {
            返回号码;
        }

        公共无效setNumber(字符串编号){
            this.number = 数字;
        }

        @覆盖
        公共字符串 toString() {
            返回 "电话{" +
                    “数字:” + 数字 +
                    '}';

        }
    }

    包 com.sample.profile;

    导入 java.util.ArrayList;
    导入 java.util.Arrays;
    导入 java.util.Collection;

    公共类个人资料{

        私有字符串名称;
        私人收藏电话;

        公共档案(){
        }

        公共配置文件(字符串名称){
            this.name = 名称;
        }

        public Profile(String name, Collection phone) {
            this.name = 名称;
            this.phone = 电话;
        }

        public void addPhone(Phone phoneNumber)
        {
            如果(this.phone == null){
                this.phone = new ArrayList();
            }
            this.phone.add(phoneNumber);
        }
        公共字符串 getName() {
            返回名称;
        }

        公共无效集合名称(字符串名称){
            this.name = 名称;
        }

        公共集合 getPhone() {
            回电话;
        }

        公共无效setPhone(收集电话){
            this.phone = 电话;
        }

        @覆盖
        公共字符串 toString() {
            返回 "个人资料{" +
                    "名称='" + 名称 + '\'' +
                    ", phone=" + Arrays.toString(phone.toArray()) +
                    '}';
        }
    }



解决方案:

我解决了以下问题:

    公共无效 insertProfileTest() 抛出 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());

        // 在里面
        Profile userProfile = new Profile("Jane Doe");
        电话 homePhone = new Phone("212");
        手机 cellPhone = new Phone("718");
        userProfile.addPhone(homePhone);
        userProfile.addPhone(cellPhone);
        最终字符串 json = MAPPER.writeValueAsString(userProfile);
        LOGGER.info("配置文件 JSON:" + json);
        LOGGER.info("电话类别:" + userProfile.getPhone().getClass().getName());

        // D B
        列表 phoneVertexList = new ArrayList();
        for (电话: userProfile.getPhone()) {
            final OVertex phoneVertex = dbSession.newVertex("Phone");
            phoneVertex.setProperty("号码", phone.getNumber());
            phoneVertexList.add(phoneVertex);
        }

        最终 OVertex profileVertex = dbSession.newVertex("Profile");
        profileVertex.setProperty("名称", userProfile.getName());
        profileVertex.setProperty("phone", phoneVertexList, OType.EMBEDDEDLIST);

        profileVertex.save();
    }

根据https://orientdb.com/docs/last/general/Types.html上的文档,我不清楚 EMBEDDEDLIST 应该是 Java 类型List<Object>但我必须使用List<OVertex >

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

    从个人资料中选择 *

    +----+-----+-------+--------+---------- ----------------+
    |# |@RID |@CLASS |姓名 |电话 |
    +----+-----+-------+--------+---------- ----------------+
    |0 |#41:0|个人资料|Jane Doe|[电话{number:212},电话{number:718}]|
    +----+-----+-------+--------+---------- ----------------+

    从电话中选择 *

    +----+-----+------+------+
    |# |@RID |@CLASS|编号|
    +----+-----+------+------+
    |0 |#33:0|电话 |212 |
    |1 |#34:0|电话 |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 交互的文档。

4

0 回答 0