0

I'm running Titan 0.3.2 with Cassandra as a data store. I'm also using rexpro-python for interacting with Titan over RexPro.

Issue & Question:

If I run this Python code:

>>> import rexpro
>>> conn = rexpro.RexProConnection('localhost', 8184, 'graph')
>>> conn.execute('g.addVertex(null, node_dict)', {'node_dict':{'my_dict':{}}})
{'_type': 'vertex', '_id': '2280164', '_properties': {'my_dict': {}}}
>>> conn.execute('g.commit()')

I can look up the resulting node in the Gremlin console:

gremlin> g.v(2280164).map
==>{my_dict={}}

And it looks like the my_dict map is created properly:

gremlin> g.v(2280164).my_dict.getClass()
==>class java.util.HashMap

However, I'm unable to update my_dict with a new key & value:

gremlin> g.v(2280164).my_dict['abc'] = 123
==>123
gremlin> g.commit()
==>null
gremlin> g.v(2280164).map
==>{my_dict={}}

If I first reset my_dict to a new object in the console, my attempt to add key abc works as expected:

gremlin> g.v(2280164).my_dict = [:]
gremlin> g.v(2280164).my_dict['abc'] = 123
==>123
gremlin> g.v(2280164).map
==>{my_dict={abc=123}}

My question: how can I update my_dict with a new KV pair on a vertex created via RexPro?


Attempted workarounds/solutions:

This same issue happens when the vertex is created with a non-parameterized version of the python script:

>>> conn.execute('g.addVertex([my_dict:[:]])')

Also, not sure if relevant for this issue, but it looks like the new map created in the console is a LinkedHashMap (whereas the python/rexpro code created a HashMap):

gremlin> g.v(2280164).my_dict.getClass()
==>class java.util.LinkedHashMap
bcm360
  • 1,437
  • 2
  • 17
  • 25

2 Answers2

3

Updating the dictionary/map that comes off a vertex property circumvents the database level since you are directly modifying the value on the heap. In other words, Titan does not know that you updated the map and therefore does not persist the change.

Always think of property values as immutable even though they might be mutable java objects because those mutations are invisible to the database.

This will work:

newdict = v.my_dict.clone()
newdict['hello']='other'
v.setProperty('my_dict',newdict)
graph.commit()
v.map
0

I tried to recreate this entirely in the REPL and couldn't. I even explicitly created a java.util.HashMap and it seemed to work fine with Titan/Cassandra. I think LinkedHashMap is the default for groovy when you do [:].

gremlin> g = TitanFactory.open('bin/cassandra.local')
==>titangraph[cassandrathrift:127.0.0.1]
gremlin> g.addVertex()
==>v[4]
gremlin> g.v(4).my_dict = new java.util.HashMap()
gremlin> g.v(4).map
==>{my_dict={}}
gremlin> g.v(4).my_dict['abc'] = 123
==>123
gremlin> g.v(4).map
==>{my_dict={abc=123}}
gremlin> g.v(4).my_dict.getClass()
==>class java.util.HashMap
gremlin> g.commit()
==>null
gremlin> g.v(4).map
==>{my_dict={abc=123}}

What happens if you don't parameterize your RexPro request? In other words, do you get different results if you do:

>>> conn.execute('g.addVertex([my_dict:[:]])')

If that works that might be a workaround for you. I know the recommendation is to "parameterize requests" via RexPro but since this script is basically static, it will cache nicely in the scriptengine at not much additional cost per request.

stephen mallette
  • 45,298
  • 5
  • 67
  • 135
  • Stephen, thanks for your response. I attempted the script via the non-parameterized version, but saw the same issue. I also attempted to edit `my_dict` via python-rexpro (instead of the Gremlin shell), but that also seemed to have no effect. – bcm360 Nov 12 '13 at 15:46
  • I also just attempted this (both insert & attempted hashmap update via python-rexpro) on a separate install of 0.4.0 running on linux (still with Cassandra and ES)-- same issue – bcm360 Nov 12 '13 at 15:54
  • Any chance you could do a quick test with a TinkerGraph to try to isolate this problem to Titan or to RexPro? – stephen mallette Nov 12 '13 at 22:03
  • Sure; If I create the vertex in the Gremlin shell (as you did above) with either a TinkerGraph or my Titan/Cassandra/ES graph, everything works just fine for me too. The issue only seems to happen when I create the vertex via RexPro and then attempt to modify (either via RexPro or Gremlin shell). – bcm360 Nov 14 '13 at 19:08
  • I'm sorry. I meant to use your python/rexpro code to create vertices in a TinkerGraph instead of Titan. Could you simply reconfigure Rexster to do that and see what the results are (I think that will help narrow down the problem a bit)? – stephen mallette Nov 14 '13 at 19:46
  • Yep absolutely-- what's the easiest way to make that adjustment to Rexster? I've tried to modify `titan-server-rexster.xml` to add the `gratefulgraph` configuration [here](http://www.tinkerpop.com/docs/wikidocs/rexster/2.1.0/Rexster-Configuration.html), but rexster doesn't seem to recognize that. – bcm360 Nov 14 '13 at 20:04
  • easiest way? just download Rexster 2.4.0 and start it with `bin/rexster.sh -s`. run your code against `emptygraph`. – stephen mallette Nov 14 '13 at 20:11
  • thanks; just pulled down a fresh copy of Rexster 2.4.0 and ran the same test code above on `emptygraph` via python-rexpro (0.1.1). Everything worked there as well: looks like it's more Titan related. – bcm360 Nov 14 '13 at 20:45
  • That helped...once I knew it had to be something related to Titan since TinkerGraph worked, i pointed Matthias at the problem. He figured it out and posted the right answer. wow.... :) – stephen mallette Nov 15 '13 at 21:40