Hello friends, I'm upgrading some code of mine to use Neo4J 2.0, which now requires a transaction on _reads_ as well as writes for anything dealing with Node/Relationships. (It used to be reading didn't require a tx)
For those that don't know Neo4J nodes and edges have a Map<String,Object> property inside them, and that's where you keep your data that would normally end up in a domain object as fields. A recent suggestion from the Neo4J site for working with Domain objects (Let's say, User.class for example) is to store the underlying node in the domain object and have getters/setters that work on the underlying node's property map. I've used that suggestion this evening and I'm wondering if this is the right decision. Here's more information: A graph service is required to create transactions. I have this available by IOC, no problem. I also have an IOC'd UserDAO which generates User.class objects from the graph database. Again, no problem there. Once the UserDAO returns a User.class to whoever asked for it, that User.class can't be read/written to without a transaction from the graph service. I don't want the domain objects to have a handle on the graph service, that doesn't seem right to me. I can't advise the domain objects because they are not covered by the IOC framework. Basically anything that can touch the domain object now has to have the ability to create a transaction. This seems like an ideal job for a custom @Neo4JTransactional, which I'd have to add to every page/component/service that might touch a User.class. Whereas with T5Hibernate, @CommitAfter is optional, this new @Neo4JTransactional would be required or else it will fail. There are plenty of times I just needed to read fields from a bean when using Hibernate, and I didn't have to worry about a transaction. For classes that are not 'covered' by IOC, such as Test classes, I'd have to get my transaction elsewhere, probably from the same DAO I get the User.class from. The Question: So does a custom Advise annotation seem like the right way to go? I'd create a tx before the method invocation, invoke it and then call tx.success afterwards, for all methods in a class. It would be a pain (and intrusive) to have to mark each method that could possibly read or write to the domain object, so I'd want to Advise the class on all methods. Luckily Neo4J doesn't seem to care about nested tx, so that shouldn't be a problem! I've looked briefly at how Spring's Neo4J Data framework handles this. Looks like it might work, but I can't add that dependency to the project right now. I could maybe borrow some code though. The other option, which I had been using previously, is this: =================== The DAO returns a User.class that has no idea what a Neo4J Node is. Neo4J can't 'detach' a node it seems, so I iterated through the Map<String,Object> and set all the properties manually in the User.class Now a T5 page or service comes along and mucks with the User object, but to save it back to the graph db I have to essentially give the User object back to the DAO and manually reattach it (lookup the original node and update properties). 1) This creates a lot of boiler plate for the detach/re-attach. 2) This becomes messy if the property that is getting updated is the same one we used to look up the Node (i.e. if the lookup value was the email address, which can be changed) I don't really have that case now, but I could foresee that problem with the other domain objects. =================== Thanks for any tips or wisdom, Dan