使用Hibernate和@LastModifiedDate进行奇怪的版本增量

时间:2017-06-11 13:17:50

标签: java spring hibernate jpa spring-boot

我使用Spring Boot 1.5.3,Spring JPA和Hibernate 5.2.10创建了一个小测试用例。当我在使用Hibernate envers的应用程序中发现奇怪的事情时,我创建了这个测试用例:我在审计表中有几行具有相同的数据。所以,如果实体没有改变,我在审计表中有了一个新行。

然后我创建了这个关注Hibernate的测试用例。我创建了一个简单的实体:

@Entity
@EntityListeners({ AuditingEntityListener.class})
public class TestEntity extends AbstractPersistable<Long> {
    private static final long serialVersionUID = -7939807161238741482L;

    private String name;

    // Trick to start version counting from 1 instead of 0
    @Version
    private int version = 1;

    @LastModifiedDate
    private LocalDateTime lastModifiedDate;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getVersion() {
        return version;
    }

    public void setVersion(int version) {
        this.version = version;
    }

    public LocalDateTime getLastModifiedDate() {
        return lastModifiedDate;
    }

    public void setLastModifiedDate(LocalDateTime lastModifiedDate) {
        this.lastModifiedDate = lastModifiedDate;
    }
}

这里没什么特别的;只是允许自动设置latModifiedDate的AuditingEntityListener。 这是测试用例:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
@TestPropertySource(locations = "classpath:test.properties")
public class HibernateTests {
    private Logger log = LogManager.getLogger();

    @Autowired
    private TestEntityRepository testEntityRepository;

    @Before
    public void setup() {
        testEntityRepository.deleteAll();
    }

    @Test
    public void checkVersionAfterUpdateWithoutChanges() {
        TestEntity testEntity = new TestEntity();
        testEntity.setName("Name");
        testEntity = testEntityRepository.save(testEntity);

        assertEquals(1, testEntity.getVersion());

        // saving again the user without changes
        testEntity = testEntityRepository.save(testEntity);

        assertEquals(1, testEntity.getVersion());

    }

}

注意我没有使用@Transactional,因为我想模拟不同的事务保存对象。 我在做什么?我创建了一个TestEntity对象,我保存了它,我检查的版本是1.这个断言成功了。然后我重新保存了相同的对象,没有任何更改,我希望Hibernate没有对数据库进行任何更新,而是断言失败,因为它返回2作为版本。

从我的实体中删除AuditingEntityListener而不是测试通过! 这是一个理想的行为吗?当对象完全没有改变时,如何避免Hibernate进行更新?

=============================================

小更新:我调试了Hibernate代码,直到遇到问题为止:TypeHelper.findDirty()。正如所料,该方法发现lastModifiedDate已更改(它返回一个数组,其中字段的索引已更改)。 在脏检查控件之后不应该更新lastModifiedDate吗?仅当某些属性发生更改时才应更新对象,但更改修改日期将使对象始终在数据库中更新。我没有看到这一点......

0 个答案:

没有答案