0

I wanted to add simple getters and setters on a class that implements VertexFrame and I used JavaHandlers for those. For those methods I didn't want to have any interaction with the database. Unfortunately there is not something like @Ignore so I don't have unexpected annotation exceptions. When I set something on the proxy and immediately I do a get after it goes through reflection, nothing is stored. Could be that I shouldn't be using JavaHandlers but something else.. Btw manager.frame returns Java Dynamic Proxy objects (java.lang.reflect.Proxy). Here is the failing test:

package com.tests.testbed;
import org.springframework.util.Assert;

import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.impls.tg.TinkerGraph;
import com.tinkerpop.blueprints.impls.tg.TinkerGraphFactory;
import com.tinkerpop.frames.FramedGraph;
import com.tinkerpop.frames.FramedGraphFactory;
import com.tinkerpop.frames.modules.javahandler.JavaHandlerModule;

public class testProxy {
    public static void main(String args[]){
        TinkerGraph graph = TinkerGraphFactory.createTinkerGraph();
        FramedGraphFactory framedFactory = new FramedGraphFactory(new JavaHandlerModule());
        FramedGraph<TinkerGraph> manager = framedFactory.create(graph);
        Vertex vertex = manager.getVertex(1);
        IVert vert = manager.frame(vertex, IVert.class);
        int testVal = 231;
        vert.setTestVar(231);
        Assert.state(vert.getTestVar() != testVal, "int was not stored!");
    }

}

---------------------

package com.tests.testbed;

import com.tinkerpop.frames.Property;
import com.tinkerpop.frames.VertexFrame;
import com.tinkerpop.frames.modules.javahandler.JavaHandler;
import com.tinkerpop.frames.modules.javahandler.JavaHandlerClass;

@JavaHandlerClass(Vert.class)
public interface IVert extends VertexFrame {
    @Property("id")
    public int getId();
    @Property("id")
    public void setId(int id);

    @JavaHandler
    public void setTestVar(int testVar);

    @JavaHandler
    public int getTestVar();
}

--------------------

package com.tests.testbed;

import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.impls.tg.TinkerGraph;
import com.tinkerpop.blueprints.impls.tg.TinkerGraphFactory;

public class Vert implements IVert {

    private Vertex vertex;
    private int id;
    private int testVar;

    public void setTestVar(int testVar){
        this.testVar = testVar;
    }

    public int getTestVar(){
        return this.testVar;
    }

    @Override
    public Vertex asVertex() {
        if (this.vertex == null){
            TinkerGraph graph = TinkerGraphFactory.createTinkerGraph();
            Vertex v = graph.getVertex(this.getId());
            this.vertex = v;
        }
        return this.vertex;
    }

    @Override
    public int getId() {
        return this.id;
    }

    @Override
    public void setId(int id) {
        this.id = id;

    }
}

Thank you very much. P.S I have already added this as an issue in case it is a bug: https://github.com/tinkerpop/frames/issues/109 I tried getting the TargetObject but I couldn't. Please let me know if there is any solution for adding non-database data that can persist on Proxies.

Michail Michailidis
  • 11,792
  • 6
  • 63
  • 106

1 Answers1

1

You've gone wrong in a couple of places, first of all:

Property key is reserved for all elements: id

Basically you can't use the property value "id" in your @Property("id") annotations.

Secondly, although it doesn't fail, your Vert class should:

  • implement JavaHandlerContext<Vertex>
  • be abstract
  • persist values using the Vertex's properties (local variables are NOT stored in the graph db!)
  • only implement/override the methods annotated with @JavaHandler

Additionally, you don't need to store the Vertex. Because your IVert interface extends VertexFrame, you have access to the Vertex using the asVertex() method.

You should definitely re-read the documentation, refer to the examples - https://github.com/tinkerpop/frames/wiki/Java-Handler

Here are the re-written/working classes. N.B. I was using Groovy - it should be exactly the same/very similar for Java.

IVert

@JavaHandlerClass(Vert.class)
public interface IVert extends VertexFrame {

    @Property("xxid")
    public int getId();

    @Property("xxid")
    public void setId(int id);

    @JavaHandler
    public void setTestVar(int testVar);

    @JavaHandler
    public int getTestVar();

}

Vert

abstract class Vert implements JavaHandlerContext<Vertex>, IVert {

    public void setTestVar(int testVar){
        asVertex().setProperty('foobar', testVar);
    }

    public int getTestVar(){
        return (int)asVertex().getProperty('foobar');
    }

}

Main method (Groovy)

def g = TinkerGraphFactory.createTinkerGraph()
FramedGraphFactory factory = new FramedGraphFactory(new JavaHandlerModule())
FramedGraph framedGraph = factory.create(g)
IVert vert = framedGraph.addVertex('myuniqueid', IVert)
vert.setId(123)
vert.setTestVar(456)
IVert vert2 = framedGraph.getVertex('myuniqueid', IVert)
assert vert2.id == 123
assert vert2.testVar == 456
Nick Grealy
  • 24,216
  • 9
  • 104
  • 119
  • Thanks, Well the Vertex property I need it for caching reasons. Because asVertex() is called multiple times.Also my question involved a testVar that WON'T be stored in the database.I have realized that is not possible since proxies are used by Tinkerpop Frames. Ids (type rid) are there for different reason it is a trick so I can use rids that Orientdb uses so don't bother with that.IVert was extending JavaHandlerContext.I forgot that in the question.I definitely need this to be concrete class because I am using it to serialized/deserialize (JSON) in Java Spring, that's why I need extra fields. – Michail Michailidis Apr 15 '15 at 17:34
  • @MichailMichailidis, I'm not sure I understand... are you still having problems persisting values on a dynamic proxy? Can you break the problem down to the "bare minimum code" to reproduce the issue (in your question)? – Nick Grealy Apr 15 '15 at 23:26
  • Of course yours works because you persist foobar in the database. I would like to have additional properties on my object that don't need to be synced with the database. I use this object as DTO so I would like to have the flexibility to set other properties too. That's one of the reasons I abandoned Tinkerpop Frames because it fails when it sees properties that are not annotated! The provided example is the bare minimum if you run it. This is not even part of my real application of course. Thanks – Michail Michailidis Apr 22 '15 at 14:03