Syncleus / Ferma

An ORM / OGM for the TinkerPop graph stack.
http://syncleus.com/Ferma
Apache License 2.0
137 stars 26 forks source link

ClassCastException: Employee$ByteBuddy$Yxytgyif cannot be cast to com.syncleus.ferma.AbstractElementFrame #12

Closed wsalembi closed 7 years ago

wsalembi commented 7 years ago

A basic vertex creation in Ferma 3.0.2 generates a ClassCastException:

java.lang.ClassCastException: com.syncleus.ferma.annotations.FermaTest$Employee$ByteBuddy$Yxytgyif cannot be cast to com.syncleus.ferma.AbstractElementFrame

    at com.syncleus.ferma.DelegatingFramedGraph.frameElement(DelegatingFramedGraph.java:243)
    at com.syncleus.ferma.DelegatingFramedGraph.frameNewElement(DelegatingFramedGraph.java:249)
    at com.syncleus.ferma.DelegatingFramedGraph.addFramedVertex(DelegatingFramedGraph.java:313)
    at com.syncleus.ferma.DelegatingFramedGraph.addFramedVertex(DelegatingFramedGraph.java:319)
    at com.syncleus.ferma.annotations.FermaTest.testCreation(FermaTest.java:54)

This is the test class. The cause is not the inner class because it doesn't work as seperate class either.

public class FermaTest {

    public static abstract class Employee implements VertexFrame {
        @Property("name")
        public abstract String getName();

        @Property("name")
        public abstract void setName(String name);

    }

    @Test
    public void testCreation() {
        Set<Class<?>> types = new HashSet<>(Arrays.asList(new Class<?>[]{Employee.class}));
        Graph g = TinkerGraph.open();

        //implies annotated mode
        FramedGraph fg = new DelegatingFramedGraph(g, true, types);

        Employee e1 = fg.addFramedVertex(Employee.class);
        e1.setName("Jeff");
    }
}
freemo commented 7 years ago

This is because your Frame is a class but implements the interface VertexFrame. That is not allowed. You have two ways in which you can resolve this:

1) Make your Frame an interface instead of a class.

public class FermaTest {

    public interface Employee implements VertexFrame {
        @Property("name")
        String getName();

        @Property("name")
        void setName(String name);
    }

    @Test
    public void testCreation() {
        Set<Class<?>> types = new HashSet<>(Arrays.asList(new Class<?>[]{Employee.class}));
        Graph g = TinkerGraph.open();

        //implies annotated mode
        FramedGraph fg = new DelegatingFramedGraph(g, true, types);

        Employee e1 = fg.addFramedVertex(Employee.class);
        e1.setName("Jeff");
    }
}

2) extend from AbstractVertexFrame instead of the VertexFrame interface.

public class FermaTest {

    public static abstract class Employee implements AbstractVertexFrame {
        @Property("name")
        public abstract String getName();

        @Property("name")
        public abstract void setName(String name);

    }

    @Test
    public void testCreation() {
        Set<Class<?>> types = new HashSet<>(Arrays.asList(new Class<?>[]{Employee.class}));
        Graph g = TinkerGraph.open();

        //implies annotated mode
        FramedGraph fg = new DelegatingFramedGraph(g, true, types);

        Employee e1 = fg.addFramedVertex(Employee.class);
        e1.setName("Jeff");
    }
}

Both examples above work. I am going to close this issue since it doesnt represent a bug or feature request. However please feel free to continue to comment on it or make any suggestions. I will continue to monitor this issue and respond.

wsalembi commented 7 years ago

I just followed your documentation and replaced extends by implements because it didn't compile

public abstract class Person extends VertexFrame {
  @Property("name")
  public abstract String getName();
freemo commented 7 years ago

Where in the documentation did you find that? I will update it.

wsalembi commented 7 years ago

Here: https://github.com/Syncleus/Ferma/blob/master/README.md

freemo commented 7 years ago

@wsalembi Thank you I just fixed this in the readme. Please let me know if you have any problems with any of the other documentation.