java - 在违反唯一约束时使用 JPA/Hibernate 和实体更新列

标签 java spring hibernate jpa spring-data

我有一个 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 的新手,因此如果有人可以提供“最佳实践”或最干净的方法来做到这一点,我将不胜感激。

作为旁注 -

  1. 我知道抛出异常(或发送某种错误)并强制用户使用 PATCH HTTP 方法可能是这里的最佳实践方案,但要求要求我这样做这边走。

  2. 调用者不会知道自动生成的 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/

相关文章:

java - 如何从 MongoRepository/QueryDSL 获取不同的字段?

Java Web 应用程序 - 属性文件噩梦

java - 当我删除 List<List<String>> 中特定索引处的元素时出现 UnsupportedOperationException?

java - Hibernate 保存实体不工作

java - 给定一个整数数组 arr,编写一个函数,当且仅当数组中每个值出现的次数唯一时返回 true

java - 为什么我的课不被接受

java - Intellij Checkstyle 给出错误 NoClassDefFoundError

java - 如何使用 EclipseLink 避免 MySQL 连接超时错误?

java - Put-Request 抛出 401 [no body] 错误,无法存储在响应实体中

java - 不同 dao 方法的相同代码包装