我能够将数据插入到 mongodb 集合中。同时 Javers 框架尝试将数据插入到 jv_snapshots 集合中。向 jv_snapshots 集合的数据插入失败并出现以下异常:
java.lang.NoSuchMethodError: com.mongodb.client.MongoCollection.insertOne(Ljava/lang/Object;)Lcom/mongodb/client/result/InsertOneResult;
at org.javers.repository.mongo.MongoRepository.lambda$persistSnapshots$3(MongoRepository.java:231) ~[javers-persistence-mongo-5.11.1.jar:na]
at java.util.ArrayList.forEach(Unknown Source) ~[na:1.8.0_231]
at java.util.Collections$UnmodifiableCollection.forEach(Unknown Source) ~[na:1.8.0_231]
at org.javers.repository.mongo.MongoRepository.persistSnapshots(MongoRepository.java:230) ~[javers-persistence-mongo-5.11.1.jar:na]
at org.javers.repository.mongo.MongoRepository.persist(MongoRepository.java:88) ~[javers-persistence-mongo-5.11.1.jar:na]
at org.javers.repository.api.JaversExtendedRepository.persist(JaversExtendedRepository.java:154) ~[javers-core-5.11.1.jar:na]
at org.javers.core.JaversCore.persist(JaversCore.java:108) ~[javers-core-5.11.1.jar:na]
at org.javers.core.JaversCore.commit(JaversCore.java:89) ~[javers-core-5.11.1.jar:na]
at org.javers.spring.auditable.aspect.JaversCommitAdvice.commitObject(JaversCommitAdvice.java:81) ~[javers-spring-5.11.1.jar:na]
at java.util.Arrays$ArrayList.forEach(Unknown Source) ~[na:1.8.0_231]
at java.util.Collections$UnmodifiableCollection.forEach(Unknown Source) ~[na:1.8.0_231]
at org.javers.spring.auditable.aspect.springdata.AbstractSpringAuditableRepositoryAspect.lambda$onSave$0(AbstractSpringAuditableRepositoryAspect.java:28) ~[javers-spring-5.11.1.jar:na]
at java.util.Optional.ifPresent(Unknown Source) ~[na:1.8.0_231]
at org.javers.spring.auditable.aspect.springdata.AbstractSpringAuditableRepositoryAspect.onSave(AbstractSpringAuditableRepositoryAspect.java:27) ~[javers-spring-5.11.1.jar:na]
at org.javers.spring.auditable.aspect.springdata.JaversSpringDataAuditableRepositoryAspect.onSaveExecuted(JaversSpringDataAuditableRepositoryAspect.java:44) ~[javers-spring-5.11.1.jar:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_231]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_231]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_231]
at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_231]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644) ~[spring-aop-5.2.5.RELEASE.jar:5.2.5.RELEASE] …Run Code Online (Sandbox Code Playgroud) 我正在使用 Spring Data REST 开发 RESTful API。现在进行审计,Spring 确实可以选择审计元数据created_date,modified_date但它们不提供实体版本控制。
目前有两个流行的实体版本库,分别是 Envers 和 Javers。我已经查看了两者的比较,但没有关于这个问题的任何文章。
那么使用 Javers 而不使用 Envers 有哪些优点和缺点呢?
我很难理解为什么以下内容没有给我相同的结果。
如果我使用 Javers 来比较两个列表(其中的项目顺序不同),那么我不会得到任何差异,因为我已指定 AS_SET 列表比较来忽略列表中项目的顺序。
如果我随后将这些列表包装为对象的属性,Javers 会返回列表的元素因列表中项目的顺序而不同。
AS_SET 应该应用于对象内的列表吗?就好像被忽视一样
public class App {
public static void main(String[] args) {
List<ListItem> list1 = ImmutableList.of(
ListItem.builder()
.itemName("item1")
.itemValue("value")
.build(),
ListItem.builder()
.itemName("item2")
.itemValue("value2")
.build()
);
List<ListItem> list2 = ImmutableList.of(
ListItem.builder()
.itemName("item2")
.itemValue("value2")
.build(),
ListItem.builder()
.itemName("item1")
.itemValue("value")
.build()
);
TopLevelClass tlc1 = TopLevelClass.builder().items(list1).build();
TopLevelClass tlc2 = TopLevelClass.builder().items(list2).build();
Diff diff = JaversBuilder.javers().withListCompareAlgorithm(ListCompareAlgorithm.AS_SET).build().compare(list1, list2);
System.out.println(diff);
Diff diffTlc = JaversBuilder.javers().withListCompareAlgorithm(ListCompareAlgorithm.AS_SET).build().compare(tlc1, tlc2);
System.out.println(diffTlc);
}
}
Run Code Online (Sandbox Code Playgroud)
以下类别:
package wibble;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
@Builder …Run Code Online (Sandbox Code Playgroud) 我在Spring boot中创建了一个类来建立一个全局的javers对象,可供所有类使用。这是我的代码。
@Component
public class JaversInstance {
public static final Javers javers;
static
{
ConnectionProvider connectionProvider = new ConnectionProvider() {
@Override
public Connection getConnection() throws SQLException {
String url = "any_url";
Properties props = new Properties();
props.setProperty("user", "test");
props.setProperty("password", "test");
DriverManager.getConnection(url, props);
System.out.println("CONNECTION PROVIDER invoked");
return DriverManager.getConnection(url, props);
}
};
JaversSqlRepository sqlRepository = SqlRepositoryBuilder
.sqlRepository()
.withConnectionProvider(connectionProvider)
.withDialect(DialectName.MYSQL).build();
System.out.println("JAVERS instance creation");
javers = JaversBuilder.javers().registerJaversRepository(sqlRepository).build();
}
private JaversInstance() {
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
JAVERS instance creation
CONNECTION PROVIDER invoked
CONNECTION PROVIDER invoked
CONNECTION …Run Code Online (Sandbox Code Playgroud) 我正在尝试为我的 Spring Boot 应用程序实现审计层。到目前为止,我尝试了两种方法。
1) 创建了 1 个审计表,其中包含字段 user_name、table_name、column_name、old_value、new_value、uuid、event_type。
每当保存任何更改时,填充审核实体并保存它。
快的
由于只有 1 个审核表,易于管理
有时它涉及太多从业务实体到审计实体的映射
必须从数据库获取旧值以填充审计实体
2)使用javers进行审计
自动创建和更新审计实体
需要管理的表数量更少
不需要旧值检索
处理具有 20 列(字段)的表(实体)中的 10 行,
使用方法 1 所花费的时间:24328 ms => 24 s
使用方法 2 所花费的时间:311292 ms => 311 s(近 12 倍)
3)没有使用Hibernate envers,因为创建的表数量会很高
考虑到上述优点和缺点,有人可以提出更好的审计想法吗?我们的目标是,
需要管理的表数量更少
更少的响应时间
模块化审计层,自动化程度高于手动程度
每个表中有 10 到 25 列。
我正在尝试为现有的遗留系统实现一个简单的差异系统。我正在使用 Javers计算多个潜在对象状态之间的差异,并将它们保存在序列化版本中。我不想在我的对象上提交更改,只需跟踪我的差异。
给定先前序列化的 Diff,有什么方法可以重新创建 Diff 对象?
这是我的用例:
我有一个基础机构,我也并不想改变。系统接收同一实体的新版本,我想知道它们与我的基本实体有何不同。我使用 Javers Diff 找到了差异并可以显示它们,并且显然通过序列化差异来持久化它们,但不会通过序列化差异从数据库中恢复它们。
我想实现相同目标的一种方法是保留整个更改的替代实体,然后在运行时计算 Diff,但是当只有几个字段发生更改时,似乎没有必要保留整个新实体。由于唯一的键,坚持我的实体的替代版本也会干扰我现有的系统。
我在Postgres中存储数据时使用此异常"ENTITY_INSTANCE_WITH_NULL_ID"(使用JPA Lazy Load)并将javers存储在MongoDB中
Spring Boot:1.4.0.RELEASE
Sprig Data JPA:1.4.0.RELEASE
Javers:2.3.0
我调试并看到如果object是一个惰性对象,则ID为null:org.javers.core.metamodel.type.EntityType:88"Object cdoId = getIdProperty().get(instance);"
最近我遇到了这个错误,
无法处理复合密钥的杰克逊中的托管/后备引用“ defaultreference”
我在Google上搜索了很多,但发现可以使用以下选项,
JsonManagedReference和JsonBackReference
但是我的情况是
Class Parent{
private int id;
@JsonManagedReference
Set<Child> childSet;
}
Class Child{
private ChildId childId;
private String name;
}
Class ChildId{
private int childKey;
@JsonBackReference
private Parent parent;
}
Run Code Online (Sandbox Code Playgroud)
如您所见,在子类中,它具有复合键。我不能更改它,因为它与数据库有关系。
有人可以帮我解决这个问题吗?
注意:我使用杰克逊2.4.3我使用Javers 1.2.9进行对象比较
更新1:
根据建议,我删除了JsonManaged和JsonBack参考注释,并将JsonIgnore添加到childId类的Parent属性中。但是我发现Javers出错了,
JaVers运行时错误-不支持Set of ValueObjects的差异
目前 Javers 在提交元数据中记录审计的用户名和时间戳,但我也想存储用户 ID。是否可以向 Javers 提交元数据添加更多字段,例如用户 ID 或 IP 地址?
我有一个 Java 8/Maven/Spring Boot 项目。我正在使用 Javers 来审核应用程序中的更改,但是我创建了一个自定义注释,该注释放置在我希望在更改时进行审核的类中的字段上方。这是一个示例类:
public class Foo {
@AuditThis
private final String someString;
private final int someInt;
@AuditThis
private final double someDouble;
private final long someLong;
@AuditThis
private final List<String> someList;
}
Run Code Online (Sandbox Code Playgroud)
调用时javers.compare(foo1, foo2)我希望它仅将字段与@AuditThis顶部的注释进行比较。因此,在这种情况下,它只会比较对象的someString, someDouble,someList字段Foo。
我知道你可以设置一个自定义比较器,所以我尝试做这样的事情:
public class AuditThisComparator implements CustomPropertyComparator<Object, ValueChange> {
@Override
public ValueChange compare(final Object left,
final Object right,
final GlobalId globalId,
final Property property) {
ValueChange change = null;
Field[] leftFields = …Run Code Online (Sandbox Code Playgroud) javers ×10
java ×6
spring-boot ×5
audit ×2
mongodb ×2
auditing ×1
comparator ×1
connection ×1
jackson ×1
maven ×1
object ×1
performance ×1
postgresql ×1
spring ×1