pietermartin / sqlg

TinkerPop graph over sql
MIT License
246 stars 51 forks source link

java.lang.IllegalStateException: Trying to remove a EdgeRole from a non owner VertexLabel #306

Closed Easy65 closed 6 years ago

Easy65 commented 6 years ago

Hello,

I try to remove a schema with the following code:

g.getTopology().getSchema(sqlgSchema).ifPresent((Schema s) -> s.remove(false));

(I copied this from other tests where it seems to work). In my test, it sometimes fails with the above error.

Is this the correct way to remove the schema? What could be the reason for this? I currently use 1.5.2-SNAPSHOT (Build-Timestamp: 2018-07-08T19:33:35Z)

Do you have any idea how to fix or circumvent this?

Here is the stack trace:

java.lang.IllegalStateException: Trying to remove a EdgeRole from a non owner VertexLabel at org.umlg.sqlg.structure.topology.VertexLabel.removeEdgeRole(VertexLabel.java:803) at org.umlg.sqlg.structure.topology.EdgeRole.remove(EdgeRole.java:92) at org.umlg.sqlg.structure.topology.Topology.removeSchema(Topology.java:1708) at org.umlg.sqlg.structure.topology.Schema.remove(Schema.java:1348) at com.asg.dis.platform.export.rochade.XmlEdgePropertiesTest.lambda$0(XmlEdgePropertiesTest.java:56) at java.util.Optional.ifPresent(Optional.java:159)

Regards, Andreas

pietermartin commented 6 years ago

Afraid I have not seen this one before.

Are you using distributed Sqlg? Running multiple JVMs pointing to the same db? Any chance you can write a test that duplicates it?

I see the code uses object equality. I'll have a look if I can see whats causing the cache to go out of sync.

Easy65 commented 6 years ago

The test runs in one JVM, but I am afraid we are using distributed Sqlg. Sorry, but the situation occurs only if the whole JUnit test suite is executed and it probably also depends on the order of the test classes and tests (JUnit uses a random order every time). What I saw yesterday was that the state persists if it occurs. So what I could do is export the schema and the sqlg schema, if the situation reoccurs. Would that help?

Easy65 commented 6 years ago

Hi Pieter,

I created a backup of a DB state where this error is reproduceable. Please let me know if this helps and if you need any further information.

This is postgres version 10.3

Regards, Andreas

From: pietermartin notifications@github.com Sent: Wednesday, 1 August 2018 20:28 To: pietermartin/sqlg sqlg@noreply.github.com Cc: Andreas Mueller andreas.mueller@asg.com; Author author@noreply.github.com Subject: [BULK] Re: [pietermartin/sqlg] java.lang.IllegalStateException: Trying to remove a EdgeRole from a non owner VertexLabel (#306)

Afraid I have not seen this one before.

Are you using distributed Sqlg? Running multiple JVMs pointing to the same db? Any chance you can write a test that duplicates it?

I see the code uses object equality. I'll have a look if I can see whats causing the cache to go out of sync.

pietermartin commented 6 years ago

Yes that will be great. How can I get it?

Easy65 commented 6 years ago

I attached it to the previous response. Seems to be removed. Can I try to send it to another e-mail address?

pietermartin commented 6 years ago

you can send it to pieter.martin@gmail.com

pietermartin commented 6 years ago

Got it, thanks

Easy65 commented 6 years ago

I found the following exception in a logfile, which is from some test running before the situation occurs. Seems to work with 2 schemas. Maybe this is the real reason or may help to understand:

17:16:11.628 [Sqlg notification merge sqlggraph[SqlGraph] (jdbc:postgresql://localhost:5432/test-db)] ERROR org.umlg.sqlg.sql.dialect.PostgresDialect - Error in Postgresql notification java.lang.IllegalStateException: edge label must be present as the in can not be there without the out. EdgeLabel: dataOfType at com.google.common.base.Preconditions.checkState(Preconditions.java:518) ~[guava-20.0.jar:?] at org.umlg.sqlg.structure.topology.VertexLabel.fromNotifyJsonInEdge(VertexLabel.java:642) ~[sqlg-core-1.5.2-SNAPSHOT.jar:1.5.2-SNAPSHOT] at org.umlg.sqlg.structure.topology.Schema.fromNotifyJsonInEdges(Schema.java:1257) ~[sqlg-core-1.5.2-SNAPSHOT.jar:1.5.2-SNAPSHOT] at org.umlg.sqlg.structure.topology.Topology.fromNotifyJson(Topology.java:1127) ~[sqlg-core-1.5.2-SNAPSHOT.jar:1.5.2-SNAPSHOT] at org.umlg.sqlg.structure.topology.Topology.fromNotifyJson(Topology.java:1078) ~[sqlg-core-1.5.2-SNAPSHOT.jar:1.5.2-SNAPSHOT] at org.umlg.sqlg.sql.dialect.PostgresDialect$TopologyChangeListener.lambda$run$0(PostgresDialect.java:3246) ~[sqlg-postgres-dialect-1.5.2-SNAPSHOT.jar:1.5.2-SNAPSHOT] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_152] at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_152] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_152] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_152] at java.lang.Thread.run(Thread.java:748) [?:1.8.0_152]

pietermartin commented 6 years ago

Yes, interesting, does this test also have dropping the schema code?

Easy65 commented 6 years ago

Yes, in this test class their is this dropping in the @After method running after every test case. But only one of the tests prints this error. Maybe its the only test in this class that writes into two schemas, maybe even with edge between vertexes in different schemas.

pietermartin commented 6 years ago

This duplicates the bug. Basically when the same edge label is used across schemas and tables.

    @Test
    public void test() throws InterruptedException {
        Vertex a1 = this.sqlgGraph.addVertex(T.label, "A.A", "name", "halo");
        Vertex b1 = this.sqlgGraph.addVertex(T.label, "B.B", "name", "halo");
        Vertex c1 = this.sqlgGraph.addVertex(T.label, "C.C", "name", "halo");
        a1.addEdge("ab", b1);
        a1.addEdge("ab", c1);
        this.sqlgGraph.tx().commit();

        this.sqlgGraph.getTopology().getSchema("A").get().remove(false);
        this.sqlgGraph.tx().commit();

        Thread.sleep(10_000);
    }
pietermartin commented 6 years ago

I pushed a fix for this. I did not actually manage to duplicate your original error but did manage to fix the java.lang.IllegalStateException: edge label must be present as the in can not be there without the out.

Can you please test it on your system.

Easy65 commented 6 years ago

When repeat the single test with the remove on the existing DB, I still get the exception (now with the new line number, so this should be the version with the fix): java.lang.IllegalStateException: Trying to remove a EdgeRole from a non owner VertexLabel at org.umlg.sqlg.structure.topology.VertexLabel.removeEdgeRole(VertexLabel.java:805) at org.umlg.sqlg.structure.topology.EdgeRole.remove(EdgeRole.java:92) at org.umlg.sqlg.structure.topology.Topology.removeSchema(Topology.java:1708) at org.umlg.sqlg.structure.topology.Schema.remove(Schema.java:1348)

I now removed and re-created the database (in the hope that the problem is some corrupt data in the sqlg schema), but it still fails with the same error.

pietermartin commented 6 years ago

Any chance you can post the test?

Easy65 commented 6 years ago

No, it uses too much functionality from our project, some via services. If I have some time later, I will try to find the test that is the prerequisite for this error to occur. Maybe I can build a single test case that reproduces the error.

Easy65 commented 6 years ago

I finally could condense the tests to this 3 actions:

First test creates 2 vertices in 2 different schema and an edge between them:

Vertex dbcol1 = g.addVertex(T.label, schema + ".Column", "name", "HCOL11"); Vertex datType = g.addVertex(T.label, schema2 + ".DataType", "name", "CHAR1"); dbcol1.addEdge("dataOfType", datType); g.tx().commit();

Second test creates 3 vertices with 2 edges in the first schema Vertex dbcol1 = g.addVertex(T.label, schema + ".Column", "name", "HCOL31"); Vertex datType = g.addVertex(T.label, schema + ".DataType", "name", "CHAR1"); dbcol1.addEdge("dataOfType", datType); Vertex datRType = g.addVertex(T.label, schema + ".DataType", "name", "rec11"); datType.addEdge("dataOfType", datRType); g.tx().commit();

Third test runs the remove of the first schema:

g.getTopology().getSchema(schema).ifPresent((Schema s) -> s.remove(false)); g.tx().commit();

Does this help?

pietermartin commented 6 years ago

Yeah that will help a lot, tx.

pietermartin commented 6 years ago

Found the bug for the schema deletion. The code was not taking into account previously delete vertex labels and ended up trying to delete the same EdgeRole twice.

Easy65 commented 6 years ago

Thanks a lot. I can confirm that the exception does no longer occur on our side. So we can close this.