我正在使用@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 沒有啟動任何事務,從錯誤消息中可以看出,刪除查詢必須在事務內部執行。
添加回答
舉報
0/150
提交
取消