Java Spring数据存储库保存未返回具有更新审核字段的实例

Java Spring数据存储库保存未返回具有更新审核字段的实例,java,spring,jpa,spring-data,spring-data-jpa,Java,Spring,Jpa,Spring Data,Spring Data Jpa,为什么repository.save(myEntity)不返回带有更新审计字段的更新实体 MyEntityRepository.save(myEntity)和随后MyEntityService.save(myEntity)生成的实例没有更新的更新日期。我已经验证了数据库中的设置是否正确,因此我知道审计正在工作。对于插入,返回实例的UpdateOn日期是正确的,但对于更新,则不正确。我不希望在每次保存后都立即执行findById,特别是当save()返回udpated的附加实例时 假设Update

为什么repository.save(myEntity)不返回带有更新审计字段的更新实体

MyEntityRepository.save(myEntity)和随后MyEntityService.save(myEntity)生成的实例没有更新的更新日期。我已经验证了数据库中的设置是否正确,因此我知道审计正在工作。对于插入,返回实例的UpdateOn日期是正确的,但对于更新,则不正确。我不希望在每次保存后都立即执行findById,特别是当save()返回udpated的附加实例时

假设UpdateOn的设置是通过@PreUpdate钩子进行的,并且该钩子是在entityManager.merge()调用期间通过repository.save()触发的,我不明白为什么不在返回的实例上设置该值

示例代码:

@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);
    }
}
@实体
@动态铜日期
@动态服务器
@表(name=“my_entity”,schema=“public”)
@SequenceGenerator(name=“pk\u sequence”,sequenceName=“my\u entity\u seq”,allocationSize=1)
@AttributeOverrides({@AttributeOverride(name=“id”,column=@column(name=“id”,columnDefinition=“int”)))
@EntityListeners(AuditingEntityListener.class)
公共类MyEntity{
受保护的整数id;
@最后修改日期
私人日期更新;
@身份证
@GeneratedValue(策略=GenerationType.SEQUENCE,generator=“pk_SEQUENCE”)
@列(name=“id”,nullable=false,columnDefinition=“bigint”)
公共整数getId(){
返回id;
}
公共无效集合id(整数id){
this.id=id;
}
@版本
@时态(TemporalType.TIMESTAMP)
@列(name=“已更新”)
公共日期getUpdateOn(){
返回UpdateOn;
}
public void setUpdatedOn(Date updatedOn){
this.updatedOn=updatedOn;
}
}
公共接口MyEntityRepository扩展了JpaRepository{}
@服务
@事务(只读=真)
公共类MyEntityService{
@自动连线
私人髓质保存库;
@交易的
公共MyEntity保存(MyEntity MyEntity){
返回repository.save(myEntity);
}
}

我遇到了完全相同的问题。我用,

repository.saveAndFlush(myEntity);
而不是

repository.save(myEntity);

我也面临同样的问题

就我而言,帮助我解决这个问题的重要项目是:
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
UserAccount UserAccount=UserAccount.builder().username(username.build();
userAccountRepository.saveAndFlush(userAccount);
final LocalDateTime previousUpdateDate=userAccount.getUpdateDate();
....
List id=Arrays.asList(userAccountId);
UserAccount UpdateUserAccount=userAccountRepository.findAllById(ids).get(0);//包含更新的审核数据字段
...
断言(actual.getUpdateDate(),是(大于(previousUpdateDate));//真的

重要的一点是,您不应该使用repository.findOne(…),因为它会缓存对对象的引用-。

您是否已调试到
AuditingEntityListener.touchForUpdate(…)
中,并查看是否调用了该方法?您确定实体确实包含更改吗?如果持久性提供程序在实体上找不到任何更改,甚至可能不会触发事件,即使我们调用
EntityManager.merge(…)
。是的,我已经触发了,并且正在调用它。实际上,我已经用一个AuditingEntityListener和我自己的@PreUpdate钩子实现了它。这两种方法都有效-更改以正确的更新日期保存到数据库中。但是从repository.save或repository.saveAndFlush返回的实例没有这些已更改的审核字段(但是所有其他已更改的数据都会正确反映)。这很奇怪。您是否有可能将其归结为一个小测试用例,并根据Spring数据JPA提交JIRA?了解您使用的JPA提供商也很有用。我会这样做的。提供程序是Hibernate 4.2.6。