在JPA事件实体上实现绝对排序

时间:2018-11-22 16:40:48

标签: java hibernate sorting jpa event-sourcing

我尝试使用Java JPA / Hibernate定义不可变的Event-Entites(事件源),并希望这些事件具有在对象创建后立即定义的绝对顺序,而不需要任何持久性(没有分布式设置,一个需要共识)

我们正在使用@CreatedDate使用自动审核属性,但由于仅在持久性过程中填充了该属性,因此我将其从列表中删除了。

我可以想到2种选择:

  1. 使用在对象创建期间查询的全局数据库序列
  2. Long ordering = System.nanoTime()

赞赏任何建议/想法。

1 个答案:

答案 0 :(得分:1)

  

希望这些事件具有已经定义的绝对顺序   在创建对象之后

  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,例如是Web服务。或者,您可以使用数据库序列(例如计数器)。