I'm failed to upgrade my application from spring boot 2.7.6 to 3.0.0 since the behavior changed, I think it is a regression.

import static org.mockito.ArgumentMatchers.matches;
import static org.mockito.BDDMockito.then;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

import javax.persistence.EntityManager;

@DataJpaTest
@EnableJpaRepositories(basePackageClasses = PostRepository.class)
@EntityScan(basePackageClasses = Post.class)
class PostRepositoryTests {

    @Autowired
    PostRepository repository;

    @Autowired
    EntityManager entityManager;

    @SpyBean
    EntityManagerInterceptor entityManagerInterceptor;

    @Test
    void testEntityManager() {
        Post p = new Post();
        entityManager.persist(p);
        then(entityManagerInterceptor).should().invoked(matches(".*persist.*"));
        p.setName("test");
        entityManager.merge(p);
        then(entityManagerInterceptor).should().invoked(matches(".*merge.*"));
        entityManager.remove(p);
        then(entityManagerInterceptor).should().invoked(matches(".*remove.*"));
    }

    @Test
    // failed with spring boot 3.0.0
    void testRepository() {
        Post p = new Post();
        p = repository.save(p);
        then(entityManagerInterceptor).should().invoked(matches(".*persist.*"));
        p.setName("test");
        repository.save(p);
        then(entityManagerInterceptor).should().invoked(matches(".*merge.*"));
        repository.delete(p);
        then(entityManagerInterceptor).should().invoked(matches(".*remove.*"));
    }

}

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Aspect
@Component
@Order(1)
public class EntityManagerInterceptor {

    @Pointcut("execution(public void javax.persistence.EntityManager.persist(..))")
    private void persist() {
    }

    @Pointcut("execution(public * javax.persistence.EntityManager..merge(..))")
    private void merge() {
    }

    @Pointcut("execution(public void javax.persistence.EntityManager..remove(..))")
    private void remove() {
    }

    @Before("persist() || merge() || remove()")
    public void beforeTransaction(JoinPoint jp) {
        invoked(jp.getSignature().toString());
    }

    public void invoked(String signature) {

    }

}

Minimal example: em-interceptor.zip

Comment From: bclozel

Maybe your pointcut definitions need updating as Spring Boot now requires the Jakarta APIs? I'm still seeing "javax.*" types here. See https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.0-Migration-Guide#jakarta-ee

Comment From: quaff

Maybe your pointcut definitions need updating as Spring Boot now requires the Jakarta APIs? I'm still seeing "javax.*" types here. See https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.0-Migration-Guide#jakarta-ee

@bclozel The code pasted here is passed with spring boot 2.7.6, so it is javax. zip package contains codes with jakarta.

Comment From: kzander91

I think this was caused by a change in Spring Data JPA, I found that there a while ago, but it looks like my comment was overlooked and then I forgot to open an issue: https://github.com/spring-projects/spring-data-jpa/commit/1bfc3595ce2e14cdc03decfe350f20e139e3c877#r82897830

Comment From: scottfrederick

Thanks @kzander91. Would you mind converting that comment into an issue in Spring Data JPA and posting a link to it here?

Comment From: kzander91

Sure: https://github.com/spring-projects/spring-data-jpa/issues/2730