Достижение абсолютного упорядочения для событийных объектов JPA - PullRequest
0 голосов
/ 22 ноября 2018

Я пытаюсь определить неизменяемые объекты событий (Event Sourcing) с помощью Java JPA / Hibernate и хочу, чтобы эти события имели абсолютный порядок, который уже определен сразу после создания объекта, до того, как произойдет какое-либо сохранение (нет распределенной установки, гденужно согласие)

Мы используем свойства автоматического аудита с использованием @CreatedDate, но я вычеркнул это из своего списка, поскольку он заполняется только во время сохранения.

Я могу представить 2 варианта:

  1. с использованием глобальной последовательности базы данных, которая запрашивается при создании объекта
  2. Long ordering = System.nanoTime()

Любой совет / идея приветствуются.

1 Ответ

0 голосов
/ 22 ноября 2018

хочет, чтобы эти события имели абсолютный порядок, который уже определен сразу после создания объекта

  1. Самое простое решение:

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

    Конечно, возможно, что два объекта будут созданы одновременно и будут иметь одну и ту же дату, но это может быть очень трудно получить.

  2. Немного сложнее - упорядочено поid, если даты равны и оба объекта сохраняются.Может быть неопределенность, если некоторые объекты еще не сохранены, но если оба сохраняются - строгий порядок гарантирован:

    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. Самый сложный вариант, но строгий порядок гарантирован: выможет создать службу счетчика в вашей JVM и создать события через фабрику, которая будет использовать этот счетчик при создании события.

    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;
        }
    }
    

    Конечно, это только пример, служба счетчика может вернуть BigInteger и быть веб-службой,например.Или вы можете использовать последовательность базы данных как счетчик.

...