我有一个“测试”实体:
@Entity
@Table(name = "TEST")
@lombok.Data
public class Test {
@Id
@jakarta.persistence.GeneratedValue(generator = "test_id_gen_key")
@org.hibernate.annotations.GenericGenerator(name="test_id_gen_key", type=org.hibernate.id.IdentityGenerator.class)
@Column(name="id", nullable = false)
private Integer id;
@Column(name="name", nullable = true, length = 10)
private String name;
}
字符串
以及TestRepository:
@Repository
public interface TestRepository extends JpaRepository<Test, Integer> {
}
型
当我尝试在TestService中进行如下更新时:
var test = new Test(10, "any name"); // the id value : 10 does not exist in the databse
testRepository.save(test);
型
然后hibernate执行merge()方法:
1.使用id值查询数据库:10人;
1.从步骤1中什么也没有得到,然后它执行一个插入SQL来生成一个新的记录。
但是在这种情况下我想要的是抛出一个异常,CrudRepository#保存方法也说“如果实体被假设存在但不存在于数据库中,也会抛出”:
/**
* Saves a given entity. Use the returned instance for further operations as the save operation might have changed the
* entity instance completely.
*
* @param entity must not be {@literal null}.
* @return the saved entity; will never be {@literal null}.
* @throws IllegalArgumentException in case the given {@literal entity} is {@literal null}.
* @throws OptimisticLockingFailureException when the entity uses optimistic locking and has a version attribute with
* a different value from that found in the persistence store. **Also thrown if the entity is assumed to be
* present but does not exist in the database**.
*/
<S extends T> S save(S entity);
型
处理这种情况的最佳方法是什么?
我扩展了SimpleJpaRepository的实现,并添加了一个update方法来调用org.hibernate.Session#update()方法,它像我预期的那样工作,但该方法已经被弃用了,我不认为这是一个完美的解决方案:
@SuppressWarnings("deprecation")
@Override
public T update(T entity) {
session().update(entity);
return entity;
}
型
1条答案
按热度按时间bpsygsoo1#
这是JPA保存函数的实现:
字符串
因此,正如您所看到的,JPA会检查实体是否存在。如果是,那么它将更新,否则JPA将插入一条新记录。如果你不想在实体不存在的情况下插入,你可以先调用findById(),如果实体不存在抛出异常,然后再调用保存()。请不要尝试修改JPA的默认行为,因为这可能会在未来导致更多问题。