Я работаю над большим проектом, который использует фреймворк Spring, где у меня есть такая услуга:
@Component
public class ExampleService{
@Autowired
ChildOfJpaRepository childOfJpaRepository;
public void fetchAndSet(ExampleParentEntity exampleParentEntity,Long id){
exampleParentEntity.setChildEntity(childOfJpaRepository.getOne(id));
}
}
ChildOfJpaRepository - это интерфейс репозитория, расширяющий JpaRepository (из пакета org.springframework.data.jpa.repository). ExampleParentEntity - это просто некоторая сущность БД, у которой есть поле ExampleChildEntity и сеттер. Когда я звоню childOfJpaRepository.getOne(id), я ожидаю получить прокси ExampleChildEntity. Однако оказалось, что мой childOfJpaRepository упакован в JdkDynamicAopProxy. Когда выполняется метод getOne, он вызывает TransactionInterceptor и через некоторое время создает транзакцию. Вот полная трассировка стека того, что происходит после выполнения getOne (это не трассировка стека ошибок, а просто то, что происходит после запуска getOne):
com.sun.proxy.$Proxy1092.getOne() org.springframework.aop.framework.JdkDynamicAopProxy.invoke() org.springframework.aop.framework.ReflectiveMethodInvocation.proceed()
org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodIntercceptor.invoke() org.springframework.aop.framework.ReflectiveMethodInvocation.proceed()
org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke() org.springframework.aop.framework.ReflectiveMethodInvocation.proceed()
org.springframework.transaction.interceptor.TransactionInterceptor.invoke() org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction() org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary() org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning()
org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation()
Моя проблема в том, что поскольку создается транзакция, вместо получения прокси-сервера ExampleChildEntity, я фактически получаю ExampleChildEntity (и мне нужен прокси). Из моих анализов кажется, что у меня проблема с конфигурациями аспектно-ориентированного программирования. Как я могу отключить эту упаковку JdkDynamicAopProxy или как изменить ее поведение (я не хочу, чтобы она вызывала создание транзакции)?
Вот реализация getOne (): github.com/spring-projects/spring-data-jpa/blob/…. Поэтому, если вы не переопределите его, все, что он делает, это вызывает getReference (), и поэтому нет причин, по которым он ведет себя иначе.
@Zeromus, к сожалению, нет
@JBNizet Я обновил свой вопрос.
Почему вы удалили фактическое сообщение об ошибке из трассировки стека? А где твой MCVE? Трассировка стека ясно показывает, что происходит некоторая проблема аспекта транзакции, что противоречит вашему собственному утверждению о том, что в вашем коде такой вещи нет. Без MCVE, вероятно, никто не сможет вам помочь.
@kriegaex - я наблюдаю эту трассировку стека в jvisualvm, поэтому сообщения об ошибке нет. Это просто наблюдение за тем, как выполняется код. Я также только заявляю, что в моем коде «похоже, нет ни аннотаций транзакций в иерархии вызовов fetchAndSet, ни каких-либо конфигураций транзакций, кроме управляемых аннотациями». Вы должны понимать, что я явно новичок в АОП и мало что знал об этом до того, как возникла проблема, и потребовались часы отладки.
И вы должны понимать, что профессиональные разработчики, проводящие свободное время для помощи другим, любят давать советы, основанные на фактах, а не на чистых предположениях. Так что не имеет значения, новичок вы в АОП или нет. Предоставьте воспроизводимое описание проблемы или, при всем уважении, решите свою проблему в одиночку. Если вы можете наблюдать трассировку стека через VisualVM, возможно, вы также можете увидеть соответствующую ошибку где-нибудь на консоли сервера или в файлах журнала. Если ошибок нет, то в чем проблема? MCVE покажет, что происходит, и вместо этого вы можете сказать, что ожидаете.
@kriegaex - Справедливый момент. Я отредактировал свой вопрос. Надеюсь, теперь стало более ясно.
Конечно, ваш репозиторий является прокси-сервером, поскольку именно так он реализуется во время выполнения. Поэтому нет, вы не можете отключить это, если не хотите удалить Spring Data JPA. Я также сомневаюсь, что проблема на самом деле связана с вызовом getOne (вы не разместили полную трассировку стека, просто фрагмент).




Может ли ChildOfJpaRepository переопределять поведение getOne?