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