Achieving absolute ordering on JPA event-entities











up vote
0
down vote

favorite












I try to define immutable Event-Entites (Event Sourcing) using Java JPA/Hibernate and want those events to have an absolute ordering that already is defined right after object-creation, before any persistence has taken place (no distributed setup where one would need consensus)



We are using automatic auditing properties using @CreatedDate but I crossed that off my list since this is only populated during persistence.



I can think of 2 options:




  1. using a global database-sequence that is queried during object-creation


  2. Long ordering = System.nanoTime()


any advice/idea appreciated.










share|improve this question




























    up vote
    0
    down vote

    favorite












    I try to define immutable Event-Entites (Event Sourcing) using Java JPA/Hibernate and want those events to have an absolute ordering that already is defined right after object-creation, before any persistence has taken place (no distributed setup where one would need consensus)



    We are using automatic auditing properties using @CreatedDate but I crossed that off my list since this is only populated during persistence.



    I can think of 2 options:




    1. using a global database-sequence that is queried during object-creation


    2. Long ordering = System.nanoTime()


    any advice/idea appreciated.










    share|improve this question


























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      I try to define immutable Event-Entites (Event Sourcing) using Java JPA/Hibernate and want those events to have an absolute ordering that already is defined right after object-creation, before any persistence has taken place (no distributed setup where one would need consensus)



      We are using automatic auditing properties using @CreatedDate but I crossed that off my list since this is only populated during persistence.



      I can think of 2 options:




      1. using a global database-sequence that is queried during object-creation


      2. Long ordering = System.nanoTime()


      any advice/idea appreciated.










      share|improve this question















      I try to define immutable Event-Entites (Event Sourcing) using Java JPA/Hibernate and want those events to have an absolute ordering that already is defined right after object-creation, before any persistence has taken place (no distributed setup where one would need consensus)



      We are using automatic auditing properties using @CreatedDate but I crossed that off my list since this is only populated during persistence.



      I can think of 2 options:




      1. using a global database-sequence that is queried during object-creation


      2. Long ordering = System.nanoTime()


      any advice/idea appreciated.







      java hibernate sorting jpa event-sourcing






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 23 at 1:13









      Aleksandr Semyannikov

      541216




      541216










      asked Nov 22 at 16:40









      hotzen

      1,5741636




      1,5741636
























          1 Answer
          1






          active

          oldest

          votes

















          up vote
          1
          down vote














          want those events to have an absolute ordering that already is defined
          right after object-creation






          1. The simpliest solution is like:



            public class SomeEntity {
            private LocalDateTime createdAt = LocalDateTime.now();
            }


            Of course it is possible that two objects will be created simultaneously and will have the same date, but it might be extremely hard to get.




          2. A bit more complex - ordered by id if dates are equal and both objects are persisted. There may be indeterminacy if some of objects is not persisted yet, but if both are persisted - strict order is guaranteed:



            public class SomeEntity implements Comparable<SomeEntity> {

            private Long id;

            private LocalDateTime createdAt = LocalDateTime.now();

            @Override
            public int compareTo(SomeEntity o) {
            int result = createdAt.compareTo(o.createdAt);
            if (result == 0) {
            if (id != null && o.id != null) {
            result = id.compareTo(o.id);
            } else if (id != null) {
            result = 1;
            } else if (o.id != null) {
            result = -1;
            }
            }
            return result;
            }
            }



          3. The most complex option but strict ordering is guaranteed: you can create counter service in your JVM and create events through factory, that will use that counter during event creation.



            public class CounterService {
            AtomicInteger counter = new AtomicInteger();
            public int getNext() {
            return counter.incrementAndGet();
            }
            }

            public class SomeEntityFactory {
            private CounterService counterService;

            public SomeEntity create() {
            return new SomeEntity(counterService.getNext());
            }
            }

            public class SomeEntity {
            private int order;

            SomeEntity(int order) {
            this.order = order;
            }
            }


            Of course, this is example only, counter service might return BigInteger and be a web service, for instance. Or you can use a database sequence like a counter.








          share|improve this answer























          • i am hesistant to use the wall-clock time (LocalDateTime.now()).
            – hotzen
            Nov 23 at 13:15










          • the CounterService would always start from 0, so this would need to be persistant. then one could use a database-sequence right-away. isnt it?
            – hotzen
            Nov 23 at 13:16










          • There is a plenty of options with counter, I wrote it just for example. DB sequence is just another representation of that approach. Please, clerify for me why are you hesistant to use LocalDateTime? I know that there are some aspects you need to pay attention to, e.g. timezones, but it can be solved. What precision do you need?
            – Aleksandr Semyannikov
            Nov 23 at 13:28










          • @hotzen I changed code in the second solution a little.
            – Aleksandr Semyannikov
            Nov 23 at 13:48










          • i am hesistant because of time skew (even if ntp)
            – hotzen
            Nov 30 at 8:22











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53435212%2fachieving-absolute-ordering-on-jpa-event-entities%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          1
          down vote














          want those events to have an absolute ordering that already is defined
          right after object-creation






          1. The simpliest solution is like:



            public class SomeEntity {
            private LocalDateTime createdAt = LocalDateTime.now();
            }


            Of course it is possible that two objects will be created simultaneously and will have the same date, but it might be extremely hard to get.




          2. A bit more complex - ordered by id if dates are equal and both objects are persisted. There may be indeterminacy if some of objects is not persisted yet, but if both are persisted - strict order is guaranteed:



            public class SomeEntity implements Comparable<SomeEntity> {

            private Long id;

            private LocalDateTime createdAt = LocalDateTime.now();

            @Override
            public int compareTo(SomeEntity o) {
            int result = createdAt.compareTo(o.createdAt);
            if (result == 0) {
            if (id != null && o.id != null) {
            result = id.compareTo(o.id);
            } else if (id != null) {
            result = 1;
            } else if (o.id != null) {
            result = -1;
            }
            }
            return result;
            }
            }



          3. The most complex option but strict ordering is guaranteed: you can create counter service in your JVM and create events through factory, that will use that counter during event creation.



            public class CounterService {
            AtomicInteger counter = new AtomicInteger();
            public int getNext() {
            return counter.incrementAndGet();
            }
            }

            public class SomeEntityFactory {
            private CounterService counterService;

            public SomeEntity create() {
            return new SomeEntity(counterService.getNext());
            }
            }

            public class SomeEntity {
            private int order;

            SomeEntity(int order) {
            this.order = order;
            }
            }


            Of course, this is example only, counter service might return BigInteger and be a web service, for instance. Or you can use a database sequence like a counter.








          share|improve this answer























          • i am hesistant to use the wall-clock time (LocalDateTime.now()).
            – hotzen
            Nov 23 at 13:15










          • the CounterService would always start from 0, so this would need to be persistant. then one could use a database-sequence right-away. isnt it?
            – hotzen
            Nov 23 at 13:16










          • There is a plenty of options with counter, I wrote it just for example. DB sequence is just another representation of that approach. Please, clerify for me why are you hesistant to use LocalDateTime? I know that there are some aspects you need to pay attention to, e.g. timezones, but it can be solved. What precision do you need?
            – Aleksandr Semyannikov
            Nov 23 at 13:28










          • @hotzen I changed code in the second solution a little.
            – Aleksandr Semyannikov
            Nov 23 at 13:48










          • i am hesistant because of time skew (even if ntp)
            – hotzen
            Nov 30 at 8:22















          up vote
          1
          down vote














          want those events to have an absolute ordering that already is defined
          right after object-creation






          1. The simpliest solution is like:



            public class SomeEntity {
            private LocalDateTime createdAt = LocalDateTime.now();
            }


            Of course it is possible that two objects will be created simultaneously and will have the same date, but it might be extremely hard to get.




          2. A bit more complex - ordered by id if dates are equal and both objects are persisted. There may be indeterminacy if some of objects is not persisted yet, but if both are persisted - strict order is guaranteed:



            public class SomeEntity implements Comparable<SomeEntity> {

            private Long id;

            private LocalDateTime createdAt = LocalDateTime.now();

            @Override
            public int compareTo(SomeEntity o) {
            int result = createdAt.compareTo(o.createdAt);
            if (result == 0) {
            if (id != null && o.id != null) {
            result = id.compareTo(o.id);
            } else if (id != null) {
            result = 1;
            } else if (o.id != null) {
            result = -1;
            }
            }
            return result;
            }
            }



          3. The most complex option but strict ordering is guaranteed: you can create counter service in your JVM and create events through factory, that will use that counter during event creation.



            public class CounterService {
            AtomicInteger counter = new AtomicInteger();
            public int getNext() {
            return counter.incrementAndGet();
            }
            }

            public class SomeEntityFactory {
            private CounterService counterService;

            public SomeEntity create() {
            return new SomeEntity(counterService.getNext());
            }
            }

            public class SomeEntity {
            private int order;

            SomeEntity(int order) {
            this.order = order;
            }
            }


            Of course, this is example only, counter service might return BigInteger and be a web service, for instance. Or you can use a database sequence like a counter.








          share|improve this answer























          • i am hesistant to use the wall-clock time (LocalDateTime.now()).
            – hotzen
            Nov 23 at 13:15










          • the CounterService would always start from 0, so this would need to be persistant. then one could use a database-sequence right-away. isnt it?
            – hotzen
            Nov 23 at 13:16










          • There is a plenty of options with counter, I wrote it just for example. DB sequence is just another representation of that approach. Please, clerify for me why are you hesistant to use LocalDateTime? I know that there are some aspects you need to pay attention to, e.g. timezones, but it can be solved. What precision do you need?
            – Aleksandr Semyannikov
            Nov 23 at 13:28










          • @hotzen I changed code in the second solution a little.
            – Aleksandr Semyannikov
            Nov 23 at 13:48










          • i am hesistant because of time skew (even if ntp)
            – hotzen
            Nov 30 at 8:22













          up vote
          1
          down vote










          up vote
          1
          down vote










          want those events to have an absolute ordering that already is defined
          right after object-creation






          1. The simpliest solution is like:



            public class SomeEntity {
            private LocalDateTime createdAt = LocalDateTime.now();
            }


            Of course it is possible that two objects will be created simultaneously and will have the same date, but it might be extremely hard to get.




          2. A bit more complex - ordered by id if dates are equal and both objects are persisted. There may be indeterminacy if some of objects is not persisted yet, but if both are persisted - strict order is guaranteed:



            public class SomeEntity implements Comparable<SomeEntity> {

            private Long id;

            private LocalDateTime createdAt = LocalDateTime.now();

            @Override
            public int compareTo(SomeEntity o) {
            int result = createdAt.compareTo(o.createdAt);
            if (result == 0) {
            if (id != null && o.id != null) {
            result = id.compareTo(o.id);
            } else if (id != null) {
            result = 1;
            } else if (o.id != null) {
            result = -1;
            }
            }
            return result;
            }
            }



          3. The most complex option but strict ordering is guaranteed: you can create counter service in your JVM and create events through factory, that will use that counter during event creation.



            public class CounterService {
            AtomicInteger counter = new AtomicInteger();
            public int getNext() {
            return counter.incrementAndGet();
            }
            }

            public class SomeEntityFactory {
            private CounterService counterService;

            public SomeEntity create() {
            return new SomeEntity(counterService.getNext());
            }
            }

            public class SomeEntity {
            private int order;

            SomeEntity(int order) {
            this.order = order;
            }
            }


            Of course, this is example only, counter service might return BigInteger and be a web service, for instance. Or you can use a database sequence like a counter.








          share|improve this answer















          want those events to have an absolute ordering that already is defined
          right after object-creation






          1. The simpliest solution is like:



            public class SomeEntity {
            private LocalDateTime createdAt = LocalDateTime.now();
            }


            Of course it is possible that two objects will be created simultaneously and will have the same date, but it might be extremely hard to get.




          2. A bit more complex - ordered by id if dates are equal and both objects are persisted. There may be indeterminacy if some of objects is not persisted yet, but if both are persisted - strict order is guaranteed:



            public class SomeEntity implements Comparable<SomeEntity> {

            private Long id;

            private LocalDateTime createdAt = LocalDateTime.now();

            @Override
            public int compareTo(SomeEntity o) {
            int result = createdAt.compareTo(o.createdAt);
            if (result == 0) {
            if (id != null && o.id != null) {
            result = id.compareTo(o.id);
            } else if (id != null) {
            result = 1;
            } else if (o.id != null) {
            result = -1;
            }
            }
            return result;
            }
            }



          3. The most complex option but strict ordering is guaranteed: you can create counter service in your JVM and create events through factory, that will use that counter during event creation.



            public class CounterService {
            AtomicInteger counter = new AtomicInteger();
            public int getNext() {
            return counter.incrementAndGet();
            }
            }

            public class SomeEntityFactory {
            private CounterService counterService;

            public SomeEntity create() {
            return new SomeEntity(counterService.getNext());
            }
            }

            public class SomeEntity {
            private int order;

            SomeEntity(int order) {
            this.order = order;
            }
            }


            Of course, this is example only, counter service might return BigInteger and be a web service, for instance. Or you can use a database sequence like a counter.









          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 23 at 13:48

























          answered Nov 22 at 17:25









          Aleksandr Semyannikov

          541216




          541216












          • i am hesistant to use the wall-clock time (LocalDateTime.now()).
            – hotzen
            Nov 23 at 13:15










          • the CounterService would always start from 0, so this would need to be persistant. then one could use a database-sequence right-away. isnt it?
            – hotzen
            Nov 23 at 13:16










          • There is a plenty of options with counter, I wrote it just for example. DB sequence is just another representation of that approach. Please, clerify for me why are you hesistant to use LocalDateTime? I know that there are some aspects you need to pay attention to, e.g. timezones, but it can be solved. What precision do you need?
            – Aleksandr Semyannikov
            Nov 23 at 13:28










          • @hotzen I changed code in the second solution a little.
            – Aleksandr Semyannikov
            Nov 23 at 13:48










          • i am hesistant because of time skew (even if ntp)
            – hotzen
            Nov 30 at 8:22


















          • i am hesistant to use the wall-clock time (LocalDateTime.now()).
            – hotzen
            Nov 23 at 13:15










          • the CounterService would always start from 0, so this would need to be persistant. then one could use a database-sequence right-away. isnt it?
            – hotzen
            Nov 23 at 13:16










          • There is a plenty of options with counter, I wrote it just for example. DB sequence is just another representation of that approach. Please, clerify for me why are you hesistant to use LocalDateTime? I know that there are some aspects you need to pay attention to, e.g. timezones, but it can be solved. What precision do you need?
            – Aleksandr Semyannikov
            Nov 23 at 13:28










          • @hotzen I changed code in the second solution a little.
            – Aleksandr Semyannikov
            Nov 23 at 13:48










          • i am hesistant because of time skew (even if ntp)
            – hotzen
            Nov 30 at 8:22
















          i am hesistant to use the wall-clock time (LocalDateTime.now()).
          – hotzen
          Nov 23 at 13:15




          i am hesistant to use the wall-clock time (LocalDateTime.now()).
          – hotzen
          Nov 23 at 13:15












          the CounterService would always start from 0, so this would need to be persistant. then one could use a database-sequence right-away. isnt it?
          – hotzen
          Nov 23 at 13:16




          the CounterService would always start from 0, so this would need to be persistant. then one could use a database-sequence right-away. isnt it?
          – hotzen
          Nov 23 at 13:16












          There is a plenty of options with counter, I wrote it just for example. DB sequence is just another representation of that approach. Please, clerify for me why are you hesistant to use LocalDateTime? I know that there are some aspects you need to pay attention to, e.g. timezones, but it can be solved. What precision do you need?
          – Aleksandr Semyannikov
          Nov 23 at 13:28




          There is a plenty of options with counter, I wrote it just for example. DB sequence is just another representation of that approach. Please, clerify for me why are you hesistant to use LocalDateTime? I know that there are some aspects you need to pay attention to, e.g. timezones, but it can be solved. What precision do you need?
          – Aleksandr Semyannikov
          Nov 23 at 13:28












          @hotzen I changed code in the second solution a little.
          – Aleksandr Semyannikov
          Nov 23 at 13:48




          @hotzen I changed code in the second solution a little.
          – Aleksandr Semyannikov
          Nov 23 at 13:48












          i am hesistant because of time skew (even if ntp)
          – hotzen
          Nov 30 at 8:22




          i am hesistant because of time skew (even if ntp)
          – hotzen
          Nov 30 at 8:22


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53435212%2fachieving-absolute-ordering-on-jpa-event-entities%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          What visual should I use to simply compare current year value vs last year in Power BI desktop

          Alexandru Averescu

          Trompette piccolo