Javers没有为集合中对象属性的更改创建快照

时间:2017-06-09 14:21:13

标签: java javers

我正在评估javers将其用于审计实体。我有一个带有ValueObjects.s的嵌套集合的实体。我希望valueobject上的每个属性都会发生变化,以生成Entity.Snapshot的快照。只有在将一个valueobject添加到集合时才会创建。在我的情况下,我将两个valueobjects添加到集合中创建了该实体的两个快照。在第三种情况下,我刚刚更改了值对象的属性,并且javers没有认识到这是对实体的更改,但为内部值对象创建了快照。

我的问题是我的假设是否有效或者跟踪集合中值对象的更改的最佳方法是什么

以下是我使用spring boot创建的简单测试的代码。

我使用的是javers版本3.2.0

我的实体如下

package com.example.javersdemo;

import com.fasterxml.jackson.annotation.JsonUnwrapped;
import lombok.Data;
import org.javers.core.metamodel.annotation.TypeName;

import javax.persistence.CollectionTable;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import java.util.List;

@Data
@Entity
@TypeName("User")
class User{
    @Id
    private String name ;


    @JsonUnwrapped
    @ElementCollection(targetClass = Hobby.class)
    @CollectionTable(name = "USER_HOBBIES")
    @JoinColumn(name = "NAME")
    private List<Hobby> hobbies;

    private User(){

    }

    public User(String name, List<Hobby> hobbies) {
        this.name = name;
        this.hobbies = hobbies;
    }
}

值对象如下

package com.example.javersdemo;

import lombok.Data;

import javax.persistence.Embeddable;

@Data
@Embeddable
public class Hobby {

    private String hobby;

    private boolean active;

    private Hobby() {

    }

    public Hobby(String hobby, boolean active) {

        this.hobby = hobby;
        this.active = active;
    }
}

我的春季数据存储库如下

package com.example.javersdemo;

import org.javers.spring.annotation.JaversSpringDataAuditable;
import org.springframework.data.repository.CrudRepository;


@JaversSpringDataAuditable
interface TestUserRepository extends CrudRepository<User,String> {

}

下面是我创建的spock集成测试,用于验证集合中对象属性的更改是否会创建新快照。

package com.example.javersdemo

import org.javers.core.Javers
import org.javers.repository.jql.QueryBuilder
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import spock.lang.Specification

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class JaversInnerValueObjectsTest extends Specification {

    @Autowired
    TestUserRepository userRepository

    @Autowired
    Javers javers


    def 'should create 6 snapshots'() {

        given:
        def hobbies = [new Hobby('Reading books', true)]
        def user = new User('John', hobbies)

        when:
        userRepository.save(user)

        hobbies = [new Hobby('Reading books', true), new Hobby('Watching Soccer', true)]

        user.hobbies = hobbies

        userRepository.save(user)

        hobbies = [new Hobby('Reading books', true), new Hobby('Watching Soccer', false)]

        user.hobbies = hobbies

        userRepository.save(user)



        then:
        QueryBuilder jqlQuery = QueryBuilder.byInstanceId('John', User)
        def snapshots = javers.findSnapshots(jqlQuery.withChildValueObjects().build())
        snapshots.size() == 6


    }

}

并且测试失败并出现以下错误

  

条件不满意:

     

snapshots.size()== 6 | | | | 5假   [Snapshot {commit:3.0,id:User / John #hobbies / 1,version:2,   (爱好:看足球)},快照{commit:2.0,id:User / John #hobbies / 1,   版本:1,(主动:真,爱好:看足球)},快照{commit:2.0,   id:User / John,版本:2,(爱好:[User / John #hobbies / 0,   User / John#hobbies / 1],name:John)},Snapshot {commit:1.0,   id:User / John #hobbies / 0,version:1,(active:true,hobby:Reading   书籍)},Snapshot {commit:1.0,id:User / John,version:1,   (爱好:[User / John#hobbies / 0],姓名:John)}]

     

预计:6

     

实际:5

1 个答案:

答案 0 :(得分:0)

在日志中有JaVers提交statistis:

13:27:44.315 [main] INFO  org.javers.core.Javers - Commit(id:1.0, snapshots:2, author:author, changes - NewObject:2), done in 71 millis (diff:71, persist:0)
13:27:44.333 [main] INFO  org.javers.core.Javers - Commit(id:2.0, snapshots:2, author:author, changes - ListChange:1 NewObject:1), done in 17 millis (diff:17, persist:0)
13:27:44.336 [main] INFO  org.javers.core.Javers - Commit(id:3.0, snapshots:1, author:author, changes - ValueChange:1), done in 3 millis (diff:3, persist:0)

在第一次提交中,创建了2个快照,因为我们在这里有2个新对象。

在第二次提交中,另外创建了两个快照:

  • 用户(实体)快照,因为用户的字段hobbies已更改 - 新项目已添加到列表中,因此ListChange
  • Hobby(value Object)快照,因为它是一个新对象

在第三次提交中,只创建了一个快照,因为用户的字段hobbies未更改。 JaVers将Value Objects和Entities集合的集合视为引用集合(GlobalId)。在这种情况下,引用不会更改。集合的状态记录如下:

["User/John#hobbies/0",
 "User/John#hobbies/1"]

第三次提交中唯一的变化是Hobby的字段更改(true-&gt; false)所以ValueObject中的ValueChange具有GlobalId User/John#hobbies/1

换句话说,当您更改某个实体拥有的值对象,并且实体状态没有更改时,将不会创建实体快照,因为它与前一个完全相同。