Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在@Transactional块末尾引发的唯一约束错误_Java_Spring_Hibernate_Jpa_Transactions - Fatal编程技术网

Java 在@Transactional块末尾引发的唯一约束错误

Java 在@Transactional块末尾引发的唯一约束错误,java,spring,hibernate,jpa,transactions,Java,Spring,Hibernate,Jpa,Transactions,假设我有一个用户类: @Entity @Data @Builder public class User { @Id @GeneratedValue(strategy = GenerationType.AUTO) Long userKey; @Column(unique = true) String someId; String name; } 这是相应的服务 @Component @Slf4j public class UserServic

假设我有一个用户类:

@Entity
@Data
@Builder
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    Long userKey;

    @Column(unique = true)
    String someId;

    String name;
}
这是相应的服务

@Component
@Slf4j
public class UserService {

    @Autowired
    UserRepository repository;

    @Transactional
    public User createUserWithId(String name, String id) {
        User userToAdd = User.builder()
                .name(name)
                .someId(id)
                .build();
        repository.save(userToAdd);
        log.info("No issue in saving");
        //some more code
        return userToAdd;
    }

}
正如您所看到的,我在User类中的someId字段上有一个唯一的约束,但是当我使用someId中的值执行方法createUserWithId时,该值已经存在于DB中,我希望在包含repository.save()的行上得到一个错误,并且不执行它后面的代码。但是代码在执行之后,我在事务块的末尾得到一个异常。我的问题是为什么会发生这种情况,在与repository对象(如本例中的repository.save)交互时通常会遇到哪些异常,以及在事务块结束时会遇到哪些类型的异常

PS我从一个简单的控制器中调用UserService,我创建了一个空的UserRepository,它只是扩展了Crudepository。为了简洁起见,我在问题中遗漏了这两个方面,但请让我知道在这里添加它们是否有意义

编辑1:根据注释中的请求添加用户存储库

@Repository
public interface UserRepository extends CrudRepository<User, Long> {
}
@存储库
公共接口UserRepository扩展了Crudepository{
}

复制时发生Uniqe错误。 spring具有数据库错误帮助器类,您可以捕获@transactional传递给控制器的控制器层上的db异常

  } catch (DataAccessException ex) {

如果数据库连接器具有标准异常抛出支持

就你而言,我想你错过了

@Transactional(readOnly = false)

该错误发生在拦截器中,因为在提交事务之前,Hibernate需要刷新对数据库的挂起更改。在刷新期间,会发生数据库异常。您可以通过调用存储库上的
saveAndFlush
手动刷新。

当我们调用

repository.save(obj); 
hibernate将该实体保存在内存中,该实体将在事务中方法的末尾持久化

执行此类操作的另一种方法是,首先应尝试获取id上的结果

repository.findById(id)

并检查它是否为null,并相应地执行保存操作。

共享
UserRepository
代码。当会话状态(来自ORM映射器)与数据库同步时,会引发异常。通常是在事务提交时。如果要强制执行,您需要在JPA
EntityManager
上调用'flush'(或者扩展
JpaRepository
而不是
crudepository
并调用
saveAndFlush
).Thank@M.Deinum当我在事务块内调用save/delete/insert时,我是否应该期望忽略所有类型的约束,或者是否存在仅在事务块末尾检查的这些约束的特定子集?
repository.findById(id)