Spring Data Repository使用更新的审计字段保存不返回的实例

时间:2013-12-04 18:02:09

标签: java spring jpa spring-data spring-data-jpa

为什么repository.save(myEntity)不会使用更新的审核字段返回更新的实体?

来自MyEntityRepository.save(myEntity)的结果实例以及随后来自MyEntityService.save(myEntity)的实例没有更新的updatedOn日期。我已经验证这是在数据库中正确设置的,所以我知道审计工作正常。返回的实例的updatedOn日期对于插入是正确的,但对于更新则不正确。我更喜欢不必在每次保存后立即执行findById,特别是如果意图是save()返回udpated,附加的实例。

假设通过@PreUpdate挂钩设置updatedOn并且在通过repository.save()调用entityManager.merge()期间触发此挂钩,我不遵循为什么不在返回的值上设置值实例

示例代码:

@Entity
@DynamicUpdate
@DynamicInsert
@Table(name = "my_entity", schema = "public")
@SequenceGenerator(name = "pk_sequence", sequenceName = "my_entity_seq", allocationSize = 1)
@AttributeOverrides({@AttributeOverride(name = "id", column = @Column(name = "id", columnDefinition = "int"))})
@EntityListeners(AuditingEntityListener.class)
public class MyEntity {

    protected Integer id;

    @LastModifiedDate
    private Date updatedOn;

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "pk_sequence")
    @Column(name = "id", nullable = false, columnDefinition = "bigint")
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @Version
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "updated_on")
    public Date getUpdatedOn() {
        return updatedOn;
    }

    public void setUpdatedOn(Date updatedOn) {
        this.updatedOn = updatedOn;
    }
}


public interface MyEntityRepository extends JpaRepository<MyEntity, Integer> { }

@Service
@Transactional(readOnly = true)
public class MyEntityService {

    @Autowired
    private MyEntityRepository repository;

    @Transactional
    public MyEntity save(MyEntity myEntity) {
        return repository.save(myEntity);
    }
}

2 个答案:

答案 0 :(得分:1)

我遇到了同样的问题。

对于我来说,帮助我解决此问题的重要事项是:
1)使用repository.saveAndFlush(...)方法

2)使用findAllById()findByYourOwnQuery()(用@Query注释)。

总体而言,我的测试用例如下:

UserAccount userAccount = UserAccount.builder().username(username).build();
userAccountRepository.saveAndFlush(userAccount);

final LocalDateTime previousUpdateDate = userAccount.getUpdateDate();
....

List<BigInteger> ids = Arrays.asList(userAccountId);    
UserAccount updatedUserAccount = userAccountRepository.findAllById(ids).get(0);  // contains updated Audit data fields

...
assertThat(actual.getUpdateDate(), is(greaterThan(previousUpdateDate)));  // true

重要的是您不应该使用repository.findOne(...),因为它缓存了对对象的引用-read more

答案 1 :(得分:-1)

我遇到了完全相同的问题。我用它来修复它,

repository.saveAndFlush(myEntity);

而不是

repository.save(myEntity);