Search code examples
javaorientdb

Joda DateTime in OrientDB Object API


I am using JDK 8, JodaTime 2.9.9 and OrientDB version 2.2.26.

Is there a way to use DateTime objects with OrientDB Object API?

Example class:

class Entity {

    private DateTime date;

    public Entity(DateTime date){
        this.date = date
    }

    public DateTime getDate(){
        return date;
    }

    public void setDate(DateTime newDate){
        this.date = newDate;
    }
}

Registering in OrientDB:

database.getEntityManager().registerEntityClass(Entity)

If I try to save it:

database.save(new Entity(DateTime.now()))

Then I get:

com.orientechnologies.orient.core.exception.OSerializationException: 
Linked type [class org.joda.time.DateTime:2017–09–12T11:50:25.709–03:00] 
cannot be serialized because is not part of registered entities.

If I try to register DateTime:

database.getEntityManager().registerEntityClass(DateTime)

And I try to save entity again:

database.save(new Entity(DateTime.now()))

Since it is a final class, javassist cannot proxy it, so I got a:

java.lang.RuntimeException: org.joda.time.DateTime is final

I don’t wanna to change my class to store a long instead of a DateTime. Is there a way to implement and register some sort of serializer and deserializer for DateTime or something that, similarly, would not interfere with my entity?


Solution

  • Ok, I find out how to do it (code in Groovy):

        def orientDbServer = OServerMain.create()
        System.setProperty("ORIENTDB_HOME", new File("").getAbsolutePath());
        orientDbServer.startup(new OServerConfiguration().with { cfg ->
            location = "memory"
            network = new OServerNetworkConfiguration(this)
            users = [new OServerUserConfiguration(name: "root", 
                                                  password: "root",
                                                  resources: "*")] as OServerUserConfiguration[]
            cfg
        })
        orientDbServer.activate()
    
        addShutdownHook {
            orientDbServer.shutdown()
        }
    
        new OServerAdmin("localhost").connect("root", "root")
                                     .createDatabase("test", "document", "memory").close()
        OObjectDatabaseTx database = 
                        new OObjectDatabaseTx("memory:localhost/test").open("admin", "admin")
    
        OObjectSerializerContext serializerContext = new OObjectSerializerContext();
        serializerContext.bind(new OObjectSerializer<DateTime, Long>() {
            @Override
            Object serializeFieldValue(Class<?> iClass, DateTime iFieldValue) {
                return iFieldValue.getMillis()
            }
    
            @Override
            Object unserializeFieldValue(Class<?> iClass, Long iFieldValue) {
                return new DateTime(iFieldValue)
            }
        }, database)
    
        OObjectSerializerHelper.bindSerializerContext(null, serializerContext)
    

    It is important that the serializerContext is registered before any entity class registration