我有一个 PUT 调用,通过 @RequestBody
将有效负载映射到以下对象:
@Entity
@Table(uniqueConstraints = @UniqueConstraint(columnNames = {"clientId", "reasonCode"}))
public class DeviceInfo implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private long id;
private int clientId;
private String reasonCode;
private int deviceValue;
... Getters and Setters here ....
}
对于 DAO 层,我有这个简单的接口(interface)
public interface DeviceInfoDao extends JpaRepository<DeviceInfo, Long> {
}
使用 Spring 将 @Autowired
放入我的服务层,并使用
deviceInfo = deviceInfoDao.save(deviceInfo);
我遇到的问题是,我稍后可能会进行另一个 PUT 调用,其中有效负载相同,只是这次 deviceValue 不同。目前,它会抛出异常,因为违反了 @UniqueConstraint
。
但是,我更希望在调用 DeviceInfoDao.save() 时发生更新,而不是抛出异常。我是 JPA 和 Hibernate 的新手,因此如果有人可以提供“最佳实践”或最干净的方法来做到这一点,我将不胜感激。
作为旁注 -
我知道抛出异常(或发送某种错误)并强制用户使用
PATCH
HTTP 方法可能是这里的最佳实践方案,但要求要求我这样做这边走。调用者不会知道自动生成的 id 值,因此让他们在下次调用时发送该值并不是一种选择。
最佳答案
没有现成的机制可以为您执行此操作。处理这种情况的常见方法是首先通过输入参数进行搜索,然后根据输出进行保存
或更新
DeviceInfo deviceInfo = deviceInfoDao.findByClientIdAndReasonCode(clientId, reasonCode);
if (deviceInfo == null) {
deviceInfo = deviceInfoDao.save(deviceInfo);
} else {
deviceInfo.setDeviceValue(deviceValue);
deviceInfoDao.update(deviceInfo);
}
关于java - 在违反唯一约束时使用 JPA/Hibernate 和实体更新列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33873260/