I tried the OrientDB Object Database API, which allows to use register Java POJOs to the database with entityManager.registerEntityClasses(packagename)
and then read write them with minimal extra effort.
However, what I would like to achieve is to register my Java POJOs as Vertices in a graph. Is there some mapping available for registering Java POJOs as Vertices?
Sorry, GraphAPI can't be bound to Object Database API. You could use TinkerPop Frames for this purpose.
Since TinkerPop Frame was very restricting for me I saved a lot of boilerplate code by making my Vertex to Object mapper whenever retrieving a Vertex from the Database. That way it almost felt that I was using objects all the time without setting individual properties etc..even though I was mainly using graph api.
This code is a basic example and it doesn't cover all the cases but only when you have a clean bean with setters on those variables that are either primitives or Strings. Also keep in mind that this is less performant than direct invocation since it uses reflection. Hope this will be useful to someone. I am also using a snippet from here (https://stackoverflow.com/a/1042827/986160) to get all the inherited fields.
public class ObjectMapper<T> {
public static List<Field> getAllFields(List<Field> fields, Class<?> type) {
fields.addAll(Arrays.asList(type.getDeclaredFields()));
if (type.getSuperclass() != null) {
fields = getAllFields(fields, type.getSuperclass());
}
return fields;
}
public Vertex mapObjToVertex(T obj, Vertex v){
if (obj == null ) { return null; }
for (Field field : getAllFields(new LinkedList<Field>(), obj.getClass())) {
field.setAccessible(true);
String name = field.getName();
String type = field.getType().getSimpleName();
boolean isPrimitive = field.getType().isPrimitive();
if(isPrimitive || type.equals("String")){
try {
Object value = field.get(obj);
if(value!=null){
v.setProperty(name,value);
}
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
return v;
}
public T mapVertexToObj(Vertex v, T obj) {
if (v == null) { return null; }
for (Field field : getAllFields(new LinkedList<Field>(), obj.getClass())) {
field.setAccessible(true);
String name = field.getName();
String type = field.getType().getSimpleName();
boolean isPrimitive = field.getType().isPrimitive();
if(!isPrimitive && !type.equals("String")) continue;
Method setter;
try {
setter = new PropertyDescriptor(name, obj.getClass()).getWriteMethod();
}
catch(IntrospectionException ie) { continue; }
try {
if(name.equals("id")){
setter.invoke(obj, v.getId().toString());
}
else {
Object storedValue = v.getProperty(name);
if (storedValue !=null){
if(type.equals("String")) setter.invoke(obj, storedValue.toString());
else if(type.equals("byte")) setter.invoke(obj, (byte)storedValue);
else if(type.equals("int")) setter.invoke(obj, (int)storedValue);
else if(type.equals("float")) setter.invoke(obj, (float)storedValue);
else if(type.equals("long")) setter.invoke(obj, (long)storedValue);
else if(type.equals("double")) setter.invoke(obj, (double)storedValue);
else if(type.equals("boolean")) setter.invoke(obj,(boolean)storedValue);
}
}
}
catch(Exception e){
e.printStackTrace();
}
}
return obj;
}
}
And it is used like that:
Entity entity = new ObjectMapper<Entity>().mapVertexToObj(v,new Entity());
or
Vertex v = new ObjectMapper<Entity>().mapObjToVertex(entity,v);
After you registered your classes, you can do:
OSchema schema = db.getMetadata().getSchema();
schema.getClass("SomeVertexClass").setSuperClass(schema.getClass("V"));
schema.getClass("SomeEdgeClass").setSuperClass(schema.getClass("E"));
however, to remove a vertex or edge with an OObjectDatabaseTx connection you cannot simply call:
db.delete(somePojo);
Instead, you need to do something like
db.command(new OSQLSynchQuery("delete vertex/edge " + somePojo.getId())).execute();
For a library which does this and cascade relations for you, see: ObjectGraphDb