6 Replies Latest reply on Nov 25, 2010 11:16 AM by Lothar Nieswandt

    Bitemporal versioning implemented in envers?

    Sebastian Komander Newbie

      Hi,

      are there any plans to implement bitemporal versioning in envers?
      I think this feature should be implemented in envers, according to temporal data with the corresponding version-reader and so on.
      It would be really nice if there would be new annotations like @Bitemporal, additional querys and readers...

      The envers+seam sample vor bitemporal data is nice, but all the logic is implemented in the application, not in the framework. I think this isn't really nice or useful. Would be better if the logic is implemented in the framework with some additional methods like get(Class, PrimaryKey, TransactionDate, ValidDate), getHistory ...

      Kind regards

      Sebastian

        • 1. Re: Bitemporal versioning implemented in envers?
          Adam Warski Master

          Hello,

          that's true that in the demo, the bitemporal logic is in the application, not in the framework, but thanks to some framework features (for example: maximializing properties in queries) this logic is quite minimal.

          It's of course possible to build a thin bi-temporal layer on top of Envers and include it in the library. However there are some things to consider, how to properly abstract the transaction/valid date, for example.

          What additional methods do you exactly have in mind and what would they do?

          --
          Adam

          • 2. Re: Bitemporal versioning implemented in envers?
            Sebastian Komander Newbie

            Hi,

            I'm playing around for some months with bitemporal versioning.
            I extended envers to support valid-dates (validFrom and validTo).
            The validFrom and validTo-Attributes can be changed with an annotation.
            The extensions uses validFrom and validTo as properties, if nothing else is annotated.
            The attributes must be a date (precision: day). I also extended the Versioned-Annotation with an attribute VersioningType to define temporality or bitemporality. The values for validity must be defined by the framework user. I extended the VersionReader for querys with valid-dates. Its also possible to display a validity-history.
            The problem ist that the whole extensions isn't really tested and some code is really "ugly".
            But the _real_ problem is support for bitemporal references. I found two possibilitys to solve the problem:
            1. create a new table which works as a reference-table like a third table for m:n-references.
            2. manualy follow references instead of cascading them through hibernate. then the code for reading/writing/.. references can be customized with a valid-date property

            Kind regards

            Sebastian

            • 3. Re: Bitemporal versioning implemented in envers?
              Adam Warski Master

              Hello,

              so you explicitly store validFrom and validTo in your entities? (I suppose that's the 'recorded' time - isn't the validTo of revision N equal to valid from of revision N+1?)

              Are bitemporal references you are referring to relations? What kind of "questions"/queries would you like to ask about those relations?

              Adam

              • 4. Re: Bitemporal versioning implemented in envers?
                Sebastian Komander Newbie

                Hi Adam,

                validFrom and validTo is explicitly stored, yes.

                The transaction-date (I think this is the same as record-date) means the timestamp when an entity is persisted. The valid-date is the date when this entity is valid to "use".

                I think the querys/questions are good examples:

                1) What do we know about the name of a person today?
                2) What do we know about the name of a person on 1. July 2007?
                3) What do we know on the 01. July 2007 about the person's name on 01. December 2009?

                A person is represented through multiple rows in the database:

                Person:
                Name|transaction-date|valid-from|valid-to

                Smith|01.01.2008|01.01.2008|31.12.9999
                Miller|01.01.2009|01.05.2009|01.06.2009
                Maier|01.01.2009|02.06.2009|31.12.9999

                On 01.01.2008 we have created a person with name "Smith". The Name "Smith" is valid from 01.01.2008 and valid to eternoty.
                On 01.01.2009 we changed the name to Miller. Miller is valid from 01.05.2009 till 01.06.2009.
                On 01.01.2009 we made another change: From 02.06.2009 the name changed from "Miller" to "Maier".

                No we can ask the following questions:

                1) What do we know about the name of a person today?
                Today = 25.08.2008
                Answer: Smith
                The last two datasets aren't known - the are recorded on 01.01.2009 - in the future.

                If we changed today to 01.02.2009 the correct answer is "Miller"

                2) What do we know about the name of a person on 1. July 2007?
                Answer: Nothing cause the person was recorded in 2008.

                3) What do we know on the 01. July 2009 about the person's name on 01. December 2009?

                Answer: Miller
                The last two datasets are known on 01.July 2009. We want to know which name is valid von December 2009, so we have to use the second dataset, cause the first one is only valid till 01.06.2009.

                The greate benefit is that you can "restore" any state of your database. You can make changes to a dataset to the past, present and the future.
                You can change the name of a person for the future cause he/she would marry next year.

                It's really difficult to version references betweeen entities in a bitemporal way cause there are no 1:n-references. Every reference becomes a M:N-referens and depends on the record/valid-date.

                validTo from revision N is validFrom of revision N+1, right!

                I hope you understand what I mean. If not I can sent you some bitemporal samples...

                Kind regards,

                Sebastian

                • 5. Re: Bitemporal versioning implemented in envers?
                  Adam Warski Master

                  Hello,

                  I think you can answer all the above questions using Envers, even using only the transaction and validFrom dates - modifying a bit the query code used in the Seam example.

                  As for relations - here Envers can help too, I think. If you have a versioned 1:n relation between a Person and an Address, you can the treat it as a n:m relation, because it is versioned. How? Quite easy: once you get hold of a historical Person object, you can just navigate to its Address - it will be the Address that was "current" at that revision.

                  --
                  Adam

                  • 6. Re: Bitemporal versioning implemented in envers?
                    Lothar Nieswandt Newbie

                    Sebastian, have you been successful with your extension? I think this is exactly what is needed for many business applications.

                    I have still not found an appropriate framework to support bitemporal versioning. There's "bitemporal" by Ervacon but I am not sure whether it has been tested in a production environment. And it does not support bitemporal relations, only bitemporal properties.

                    Envers' approach sounds so promising. To separate actual and versioned data sounds like a really good idea. I also like the revision approach adapted by Subversion. How wonderful it would be if it supported effective time...