为了账号安全,请及时绑定邮箱和手机立即绑定

使用 spring data jpa 存储库在 Hql 查询后刷新()

使用 spring data jpa 存储库在 Hql 查询后刷新()

catspeake 2023-06-21 15:37:52
我正在使用@Queryspring 数据 jpa 存储库中的注释编写一些 hql 查询。我知道我可以使用存储库接口中的方法,但出于学习目的,我正在明确编写它们。这是我的主课@SpringBootApplicationpublic class Main implements CommandLineRunner {    @Autowired    PersonRepository personRepository;    public static void main( String[] args ) {        SpringApplication.run(Main.class, args);    }    /**     * if we delete the transactional annotation-> we get an exception     */    @Override    @Transactional    public void run( String... args ) throws Exception {        saveOperation();        deleteOperationUsingHql();    }    private void saveOperation() {        Person p = new Person("jean", LocalDate.of(1977,12,12));        personRepository.save(p);    }    private void deleteOperationUsingHql() {        personRepository.deleteUsingHql(1L);        personRepository.flush();        Optional<Person> p = personRepository.findById(1L);        if (p.isPresent()){            System.out.println("still present");        }    }}我的 personRepository 界面public interface PersonRepository  extends JpaRepository<Person, Long> {      @Query(value = "select p from Person p where p.id=?1")      List<Person> getById( Long id);      @Modifying      @Query(value = "delete from Person p where p.id=:id")      void deleteUsingHql( Long id );}人物类@Entity@Table(name = "Person")public class Person {    @Id    @GeneratedValue(strategy = GenerationType.IDENTITY)    private Long id;    private String name;    private LocalDate date;   // constructors,getters...omitted for brievety}一切都运行良好,但是对于deleteOperationUsingHql(),即使我从数据库中删除了这个人,即使我将修改刷新到数据库,方法id=1仍然返回了那个人findById(1L)。我应该怎么做才能返回findById(1L)一个空的可选。我的第二个问题是关于注释@Transactional,我知道它的详细工作原理,但我不知道为什么如果我们删除它,我们会得到以下异常引起原因:javax.persistence.TransactionRequiredException:执行更新/删除查询@Transactional有人可以解释为什么我在删除时遇到此异常。
查看完整描述

1 回答

?
www说

TA贡献1775条经验 获得超8个赞

即使我从数据库中删除了这个人,即使我将修改刷新到数据库中,id=1 的人仍然由 findById(1L) 方法返回

这很正常,因为您使用查询来删除人员,而不是实际使用存储库(以及 EntityManager)删除方法。查询完全绕过会话缓存,因此 Hibernate 不知道此人已被删除,并返回其缓存中的实例。解决方案:不要使用查询。替代解决方案,删除后清除缓存(例如通过将注释clearAutomatically的标志设置Modifying为 true)。

有人可以解释为什么在删除 @Transactional 时我会收到此异常。

因为 when@Transactional被删除,在执行该方法之前,SPring 没有启动任何事务,从错误消息中可以看出,删除查询必须在事务内部执行。


查看完整回答
反对 回复 2023-06-21
  • 1 回答
  • 0 关注
  • 133 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信