0

I need to create a model in which changes to entities (essentially a transaction) need to be persisted separately and go through a process of approval (by other users) before being actually applied.

Think of it as creating a branch in Git (representing a transaction in JPA/Hibernate) and requesting it to be merged to be back. A desir(ed|able) side-effect of this is that this also covers auditing - as the history will be present already, but note that this is NOT the primary reason for the question (that would be addressed by something like Envers, for example).

Most of the entities can participate in this and I would like to avoid duplicating everything in order to have the "official entity" separate from "staging entities" or similar. Staging would need to cover inserts, updates and deletes (perhaps using tombstones).

I am trying to simplify this for most of the development and push as much of this out to Hibernate / 3rd party libraries and, if not there, to a framework that I would have to create. Ideally all regular transaction commits would actually be against the staging areas (potentially create it) - the only exception would be the final / apply action, which may be treated specially.

One of the main challenges for me is dealing with the fact that normal use of entities and their ids (primary keys) will point to the sole/master copy of the entity - I don't know how to redirect those elsewhere.

Does anyone have any suggestions?

Learner
  • 1,215
  • 1
  • 11
  • 26
  • One line of thinking: use composite ids and change a part of them to scope the changes outside "master". This could be done @PreUpdate/@PreInsert/... But this opens up a question of how to overlay staging data over the master for a given scope and what would happen with relationships with data only in master... Another line of thinking: Get detected changes from Hibernate (how?) and automagically create a separate graph. Same overlay question remains. – Learner Jan 02 '19 at 21:11
  • Perhaps [Hibernate Envers](https://hibernate.org/orm/envers/) could help? (You'll probably also want soft deletions) – crizzis Jan 03 '19 at 08:02
  • Envers solves a somewhat different issue (as noted). I will use something similar to soft deletions (I called them tombstones) but these are probably going to end up in separate/dedicated tables for reasons unrelated to this question. – Learner Jan 03 '19 at 15:23
  • A search has taken me to see this: https://github.com/michail-nikolaev/jpa-hibernate-branches ... which *MAY* sound like what I need but is inactive and looks only like a stub/beginning of a project... (no documentation). – Learner Jan 03 '19 at 15:24
  • Sorry, didn't notice you'd already mentioned envers. My point was that you could try using envers for your use case if you accepted that the current entity version != last accepted entity version (you would need to keep track of the version number of the last accepted version separately from envers) – crizzis Jan 03 '19 at 17:02
  • @crizzis: Thank you for your thoughts but that allows for at most one staged version per entity. I neglected to clarify that - there can be multiple, just like multiple branches in git... and, yes, they can conflict and I'd have to deal with that. That'll be "easy" once I figure out the rest. Presently (almost) giving up on ultimate simplicity, have to figure out how to best copy/clone entities to model this explicitly. – Learner Jan 03 '19 at 18:47
  • TBH I don't see why envers would only allow for one staged version. To my mind, if you keep two additional pieces of metadata for entity roots, i.e. (1) 'am I the head revision', and (2) 'which revision is my parent', then you're all set (the fact that envers thinks of consecutive revisions as being 'on top of each other' does not mean your app should, too). But maybe I'm missing something. – crizzis Jan 04 '19 at 04:06

0 Answers0