I have a basic SpringBoot app. using Spring Initializer, JPA, embedded Tomcat, Thymeleaf template engine, and package as an executable JAR file. I have created this Repository class:
@Repository
public interface MenuRepository extends CrudRepository<Menu, Long> {
@Cacheable("menus")
@Query("select cur from Menu cur where cur.MenuId = ?1")
Menu findMenuByMenuId (String MenuId);
@Cacheable("menus")
@Query("select cur from Menu cur where lower (cur.symbol) = lower (?1) ")
Menu findMenuBySymbol (String symbol);
and this service:
@Service
public class MenuService {
@Autowired
protected MenuRepository menuRepository;
@Autowired
MenuPriceService menuPriceService;
@Transactional
public Menu save (Menu menu) {
return menuRepository.save (menu);
}
@Transactional
public void delete (Menu menu) {
menuRepository.delete (menu);
}
..
}
}
and this JUNIT test:
@Test
@Transactional
public void testDelete () {
String menuName = System.currentTimeMillis()+"";
Menu menu = new Menu();
menu.setMenuId(menuName);
menuService.delete (menu);
}
but this is what I see in the console
Hibernate:
insert
into
t_menu
(...)
values
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
While removing @Transactional
as suggested in another answer might make the behavior go away, I'd question the validity of the test.
The question really is: why do you try to delete an entity that is not in the database?
If you simulate the case where don't know if the entity exists, use deleteById
it will throw an exception when the id is not present in the database and you can, of course, catch that.
delete(T entity)
is implemented through SimpleJpaRepository.delete(T entity)
which basically contains this single line of code.
em.remove(em.contains(entity) ? entity : em.merge(entity));
As you can see it does a merge
on the entity if the entity isn't present in the EntityManager
. Without the merge
you'd might end up with duplicate entities in the session if another instance with same class and Id does exist in the EntityManager
. But since your entity doesn't exist at all this triggers an insert into the database.
You might think it as this: You create an instance, you make the EntityManager
know about it (by telling it to delete it) and you delete it, so these are the steps that need to occur in the database -> insert + delete.