Mar*_*ijk 22 java hibernate spring-data-rest
我正试图在一个@HandleBeforeSave事件中得到旧实体.
@Component
@RepositoryEventHandler(Customer.class)
public class CustomerEventHandler {
private CustomerRepository customerRepository;
@Autowired
public CustomerEventHandler(CustomerRepository customerRepository) {
this.customerRepository = customerRepository;
}
@HandleBeforeSave
public void handleBeforeSave(Customer customer) {
System.out.println("handleBeforeSave :: customer.id = " + customer.getId());
System.out.println("handleBeforeSave :: new customer.name = " + customer.getName());
Customer old = customerRepository.findOne(customer.getId());
System.out.println("handleBeforeSave :: new customer.name = " + customer.getName());
System.out.println("handleBeforeSave :: old customer.name = " + old.getName());
}
}
Run Code Online (Sandbox Code Playgroud)
如果我尝试使用该findOne方法获取旧实体,但这将返回新事件.可能是因为当前会话中的Hibernate/Repository缓存.
有没有办法获得旧实体?
我需要这个来确定给定的属性是否被更改.如果属性是更改,我需要执行一些操作.
Gab*_*man 13
如果使用Hibernate,您只需从会话中分离新版本并加载旧版本:
@RepositoryEventHandler
@Component
public class PersonEventHandler {
@PersistenceContext
private EntityManager entityManager;
@HandleBeforeSave
public void handlePersonSave(Person newPerson) {
entityManager.detach(newPerson);
Person currentPerson = personRepository.findOne(newPerson.getId());
if (!newPerson.getName().equals(currentPerson.getName)) {
//react on name change
}
}
}
Run Code Online (Sandbox Code Playgroud)
感谢Marcel Overdijk创建票证 - > https://jira.spring.io/browse/DATAREST-373
我看到了这个问题的其他解决方法,并且想要提供我的解决方法,因为我认为实现起来非常简单.
首先,在您的域模型中设置一个瞬态标志(例如Account):
@JsonIgnore
@Transient
private boolean passwordReset;
@JsonIgnore
public boolean isPasswordReset() {
return passwordReset;
}
@JsonProperty
public void setPasswordReset(boolean passwordReset) {
this.passwordReset = passwordReset;
}
Run Code Online (Sandbox Code Playgroud)
其次,检查EventHandler中的标志:
@Component
@RepositoryEventHandler
public class AccountRepositoryEventHandler {
@Resource
private PasswordEncoder passwordEncoder;
@HandleBeforeSave
public void onResetPassword(Account account) {
if (account.isPasswordReset()) {
account.setPassword(encodePassword(account.getPassword()));
}
}
private String encodePassword(String plainPassword) {
return passwordEncoder.encode(plainPassword);
}
}
Run Code Online (Sandbox Code Playgroud)
注意:对于此解决方案,您需要发送另外一个resetPassword = true参数!
对我来说,我使用以下请求有效负载向我的资源端点发送HTTP PATCH:
{
"passwordReset": true,
"password": "someNewSecurePassword"
}
Run Code Online (Sandbox Code Playgroud)
您目前在休眠状态下使用spring-data抽象。如果查找返回新值,则表明spring-data已将对象附加到休眠会话。
我认为您有三种选择:
save当另一个感染具有已知的相同类型和ID时,您就不能将对象设为休眠会话。在这种情况下使用merge或evict。onFlushDirty具有两个值作为参数。不过请注意,休眠状态通常不会查询您的先前状态,而只是保存一个已持久的实体。取而代之的是,在数据库中发出一个简单的更新(不选择)。您可以通过在实体上配置select-before-update来强制选择。| 归档时间: |
|
| 查看次数: |
9465 次 |
| 最近记录: |