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

标签 java hibernate sorting jpa event-sourcing

我尝试使用 Java JPA/Hibernate 定义不可变的事件实体(事件源),并希望这些事件具有在对象创建之后、发生任何持久性之前就已定义的绝对顺序(没有分布式设置,其中需要达成共识)

我们正在使用 @CreatedDate 自动审核属性,但我将其从列表中删除,因为它仅在持久性期间填充。

我能想到两个选择:

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

任何建议/想法表示赞赏。

最佳答案

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

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

关于java - 在 JPA 事件实体上实现绝对排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53435212/

相关文章:

java - Android-Fragment出现在ImageView后面

C-Qsort : Sort name in ascending order and grade in descending order

c++ - 如何打印数组元素的索引号?

java - JTable header 中 JButton 上的 ActionListener 卡住应用程序

java - 为什么原始数组是用另一种方法修改的?

java - hibernate 序列不存在

java - 数据未插入到 Spring-Hibernate-envers webapp 中的审计表中

java - 执行加载命令时出错 : org. hibernate.exception.SQLGrammarException: 无法在线程 "main"中提取 ResultSet 异常

sorting - Swift AddressBook - 复制源中的所有人员,但存在排序问题

java - 初始化静态最终变量