@LastModifiedDate导致数据库中的其他更新

时间:2018-05-05 23:43:26

标签: java hibernate spring-boot spring-data-jpa auditing

有点奇怪,但是当我的实体使用@LastModifiedDate注释时,它会在保存新对象时触发其他更新。
如果我设置@EnableJpaAuditing(modifyOnCreate = false),那么它只是插入,但在保存新实体时没有设置上次修改日期。

有没有办法让它在插入时设置最后修改日期,而不会向数据库发送额外更新或者我错过了什么?

这是我的代码:

var paragraphs = d3.selectAll("p");

d3.interval(function() {
  toggleClass(paragraphs, "foo");
  console.log(paragraphs.attr("class"))
}, 1000)

function toggleClass(selection, className) {
  selection.classed(className, !selection.node().classList.contains(className))
}

带有getter的抽象实体(使用getter,因为我在其他地方使用Hibernate):

<script src="https://d3js.org/d3.v5.min.js"></script>
<p class="foo someOtherClass">Foo</p>
<p class="foo someOtherClass">Bar</p>
<p class="foo someOtherClass">Baz</p>

实体类

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories
@EnableJpaAuditing(auditorAwareRef = "auditorProvider")
public class JpaConfig {

    @Bean
    public AuditorAware<String> auditorProvider() {
        return () -> System.getProperty("user.name", "undefined");
    }
}

回购:

@MappedSuperclass
public abstract class AbstractGenericJson extends GenericJson {

    private DateTime createdDate;
    private DateTime lastModifiedDate;
    private String createdBy;
    private String lastModifiedBy;

    @Column(name = "audit_create_ts", nullable = false, updatable = false)
    @CreatedDate
    @Convert(converter = JodaDateTimeConverter.class)
    public DateTime getCreatedDate() {
        return createdDate;
    }

    public void setCreatedDate(DateTime createdDate) {
        this.createdDate = createdDate;
    }

    @Column(name = "audit_update_ts")
    @LastModifiedDate
    @Convert(converter = JodaDateTimeConverter.class)
    public DateTime getLastModifiedDate() {
        return lastModifiedDate;
    }

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

    @Column(name = "audit_user_tx", updatable = false)
    @CreatedBy
    public String getCreatedBy() {
        return createdBy;
    }

    public void setCreatedBy(String createdBy) {
        this.createdBy = createdBy;
    }

    @Column(name = "audit_upd_user_tx")
    @LastModifiedBy
    public String getLastModifiedBy() {
        return lastModifiedBy;
    }

    public void setLastModifiedBy(String lastModifiedBy) {
        this.lastModifiedBy = lastModifiedBy;
    }
...

我的测试:

@Entity
@EntityListeners(AuditingEntityListener.class)
public class ConsumerInteraction extends AbstractGenericJson {
    private UUID uuid;

    @Id
    @GeneratedValue
    @Column(name = "uuid")
    public UUID getId() {
        return uuid;
    }
...

日志,显示两个Touched事件,一个用于null uuid,然后在uuid生成之后再生一个,据我所知是后续更新的原因,因为没有其他字段被修改。

@Repository
public interface InteractionRepo extends JpaRepository<ConsumerInteraction, UUID>{}

使用Spring Boot jpa 1.5.12和Hibernate 5.2.16.Final。

很抱歉很长的帖子,但我即将放弃使用@LastModifiedDate。谢谢!

2 个答案:

答案 0 :(得分:0)

发现默认TimeZone的问题。显然,lastmodifieddate似乎是在本地时区设置的,而我使用UTC作为Hibernate。在调试时,我注意到lastModifiedDate总是将我的实体渲染为脏,因为时间戳的时区不匹配。

更新了基类以使用java.util.Date作为时间戳并从Joda DateTime中删除了转换器,现在看来问题已解决。

答案 1 :(得分:0)

问题可能出在转换器的实现上。这是一个已知的奇怪情况,与对Hibernate进行脏检查有关。选中this article