即使没有任何变化,Spring Auditable 实体也会被修改
Posted
技术标签:
【中文标题】即使没有任何变化,Spring Auditable 实体也会被修改【英文标题】:Spring Auditable entity is being modified even when nothing has changed 【发布时间】:2015-02-16 09:12:40 【问题描述】:注意:这是一个复杂的问题,所以我希望我已经涵盖了相关部分。如果没有,我将根据要求编辑并添加更多信息。
我们使用 Spring (4.1.0) 和 Hibernate (4.3.6),并且我们定义了一个基类,我们的所有实体都扩展名为 BaseAuditableEntity
(代码如下)。当在 @Transactional 方法中加载任何实体,然后对其进行修改和保存时,该实体的 modified_by_user_id
和 modified_ts
都将使用登录用户的 ID 进行更新,并执行正在进行的任何更改。
我们的问题是,每当在这些@Transactional
方法之一中加载AppUser
(也扩展了BaseAuditableEntity)时,它也会看到modified_by_user_id
和modified_ts
被设置,即使它还没有被设置修改的。这会产生一个问题,因为当我们不需要时,几乎每个请求都会写入我们的用户表。请注意,这也可能会影响 @Transactional
不显式加载 AppUser
的方法,因为 AuditorBean
会加载 AppUser
本身。
我假设这与 AppUser 实体是 BaseAuditableEntity 本身的一部分这一事实有关。有人可以证实这一点吗?有没有办法解决这个问题?
我们的 BaseAuditableEntity
类,包括 AppUser 在内的每个实体都扩展:
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseAuditableEntity implements Auditable<AppUser, Long>
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "hibernate_sequence")
@SequenceGenerator(name = "hibernate_sequence", sequenceName = "blah_sequence", allocationSize = 1)
@Column(name = "id")
private Long id;
@CreatedBy
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "created_by_user_id")
private AppUser createdBy;
@LastModifiedBy
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "modified_by_user_id")
private AppUser lastModifiedBy;
@Column(name = "created_ts")
@CreatedDate
@Temporal(TemporalType.TIMESTAMP)
private Date createdDate;
@Column(name = "modified_ts")
@LastModifiedDate
@Temporal(TemporalType.TIMESTAMP)
private Date lastModifiedDate;
// ...
我们的JpaConfig
:
@Configuration
@EnableJpaRepositories(basePackages =
"blah.blah.blah")
@ComponentScan(basePackageClasses = AuditorBean.class)
@EnableTransactionManagement
@EnableJpaAuditing(auditorAwareRef = "auditorBean")
public class JpaConfig extends BaseConfig
// ...
还有我们的AuditorBean
:
@Component
public class AuditorBean implements AuditorAware<AppUser>
@Override
public AppUser getCurrentAuditor()
// omitting some code that finds a user. I think the only relevant thing here
// is that we're using the repo to find the user by ID and not using an
// entity that's already been loaded
return userRepository.findOne(id);
【问题讨论】:
【参考方案1】:我的建议是保持审计简单和定义
@CreatedBy
private Long createdBy;
没有实际关联,只存储 AppUser 的 ID。
@组件 公共类 AuditorBean 实现 AuditorAware
@Override
public Long getCurrentAuditor()
// .... find out the id
return id;
【讨论】:
以上是关于即使没有任何变化,Spring Auditable 实体也会被修改的主要内容,如果未能解决你的问题,请参考以下文章
为啥即使源代码没有变化,Gradle 的“构建”任务也不是最新的?