我正在使用带有 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 交互的文档。