我正在使用hibernate envers来审计我的表的数据并保存在OracleDB中。我正在使用Spring数据弹性搜索通过Java代码读取并保存到弹性搜索索引中的审计数据。我有一个复合键(id和rev),它定义了一个唯一的行来保存数据,但对于弹性搜索,我不能提供复合键。它只接受rev(标识符)列并替换数据。
Hibernate envers背景信息:rev是hibernate提供的默认标识符,对于同时修改的记录列表,它创建相同的rev id:
Eg: id rev comments
1 1 newly created
2 1 newly created
1 2 modified
2 2 modified
前2行是同时创建的,下次我修改这两行并更新时,Hibernateenvers会为1次保存创建相同的rev id。
@Entity
@IdClass(MyEmbeddedId.class)
@Document(indexName = "#{@indexName}", type = "my-document", shards = 1, replicas = 0, refreshInterval = "-1")
@Getter @Setter
public class MyClassAudit {
@Id
private Long id;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@org.springframework.data.annotation.Id --> (this is for elastic search _id)
private Long rev;
}
@Getter @Setter
public class MyEmbeddedId implements Serializable {
private Long id;
private Long rev;
}
Java代码:
List<MyClass> list = repository.findById(id);
elasticSearchRepository.saveAll(list)
弹性搜索仓库接口:
public interface MyElasticSearchRepository extends GenericSearchRepository<MyClassAudit, Long> {}
当我将数据保存到弹性搜索时,所有4条记录都应按示例保存,但只有2条记录保存如下:
_id id rev comments
1 2 1 newly created
2 2 2 modified
这是因为在弹性搜索中以rev作为标识符,并且正在更新第二条记录。
如何使弹性搜索考虑复合键来维护唯一记录?PS:_id是弹性搜索标识符。由于rev具有Spring数据注释id,因此在弹性搜索中将rev视为标识符
Elasticsearch本身没有复合键的概念。Spring Data Elasticsearch采用@Id
注释元素并使用它的toString()
方法为Elasticsearch创建id条目(并将字段存储在源中)。
所以——没有试过——你可以使用你的MyEmbeddedId
类作为你的MyClass审核
类的字段属性,并用@Id
对其进行注释。但是你必须在你的类中有这个属性,它不会被合成。
这可能会与hibernate的注释冲突,但我认为在存储之间共享一个实体并使用混合注释不是一个好主意。