Метод с @Transactional, вызываемый на цели, а не на экземпляре проксиJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Метод с @Transactional, вызываемый на цели, а не на экземпляре прокси

Сообщение Anonymous »

В настоящее время я переношу один из своих проектов из «самонастраиваемой пружины» в Spring Boot. Хотя большая часть материала уже работает, у меня проблема с методом @Transactional, когда при его вызове контекст не присутствует, как было установлено ранее, из-за вызова «целевого» экземпляра вместо «прокси». экземпляр (я постараюсь уточнить ниже).
Сначала урезанный вид моей иерархии классов:

@Entitypublic class Config {
// поля и прочее
}

public интерфейс Exporter {

int startExport() бросает ExporterException;

void setConfig(Config config);
}

публичный абстрактный класс ExporterImpl реализует Exporter {
защищенную конфигурацию конфигурации;
@Override
public Final void setConfig(Config config) {
this.config = config;
// this.config является допустимым экземпляром конфигурации здесь
/>
@Override
@Transactional(readOnly = true)
public int startExport() бросает ExporterException {
// this.config здесь имеет значение NULL
/>
// другие методы, включая абстрактный для подкласса
}

@Scope("prototype")
@Service("cars2Exporter")
публичный класс Cars2ExporterImpl расширяет ExporterImpl {

// переопределяем абстрактные методы и некоторые другие
// не трогаем startExport()
}

// есть другие реализации ExporterImpl тоже
// во всех реализациях возникает проблема

код вызова такой:

@Inject
частный поставщик cars2Exporter;

public void ScheduleExport(Config config) {
Exporter Exporter = cars2Exporter.get();
Exporter.setConfig(config);
Exporter.startExport();
// на самом деле я обертываю это здесь в класс, реализующий runnable
// и помещаю его в очередь ` TaskExecutor`, но проблема возникает
// и при прямом вызове. :(


В чем именно проблема?
В вызове startExport() поле config ExporterImpl имеет значение null, хотя оно было установлено прямо перед этим.
Что я нашел на данный момент:
С точкой останова в экспортере. startExport(); Я проверил идентификатор экземпляра экспортера, показанный отладчиком eclipse, во время написания этого поста это 16585. Продолжаем выполнение в вызове/первой строке startExport() где я еще раз проверил идентификатор (на этот раз), ожидая, что он будет таким же, но понимая, что это не так. Здесь это 16606... поэтому вызов startExport(). выполняется для другого экземпляра класса... в предыдущем раунде отладки я проверил, к какому экземпляру/идентификатору относится вызов setConfig()... к первому (16585 в этом case). Это объясняет, почему поле конфигурации в экземпляре 16606 имеет значение null.
Чтобы понять, что происходит между строкой, в которой я вызываю Exporter.startExport();, и фактическим значением. первую строку startExport() Я щелкнул шаги между этими обеими строками в отладчике eclipse.
Там я дошел до строки 655 в CglibAopProxy, которая выглядит следующим образом:
retVal = new CglibMethodInfection(proxy, target, метод, args, targetClass, Chain, MethodProxy).proceed();

проверка аргументов здесь я обнаружил, что прокси — это экземпляр с идентификатором 16585, а целевой — экземпляр с 16606.
к сожалению, я не так уж глубоко разбираюсь в вещах, которые нужно знать если так и должно быть...
Мне просто интересно, почему есть два экземпляра, которые вызываются разными методами. вызов setConfig() переходит к экземпляру прокси, а вызов do startExport() достигает целевого экземпляра и, следовательно, не имеет доступа к ранее установленной конфигурации...
Как уже упоминалось, проект был перенесен на Spring Boot, но раньше мы уже использовали версию Athens-RELEASE Spring Platform bom. Насколько я могу судить, там не было никаких специальных конфигураций AOP перед миграцией и никаких явно заданных значений после миграции.
Чтобы решить эту проблему (или хотя бы как-то работать), я уже попробовал несколько вещи:
  • удалить @Scope из подкласса
  • переместить @Transactional с уровня метода в класс
  • переопределить startExport() в подклассе и поместить сюда @Transactional
  • добавить @EnableAspectJAutoProxy в класс приложения (я даже не смог войти в систему — нет сообщения об ошибке)
  • установите для Spring.aop.proxy-target-class значение true
  • вышеупомянутое в разных комбинациях...
В настоящее время я не знаю, как вернуть эту работу...
Заранее спасибо
*надеется, что кто-нибудь сможет помочь*

Подробнее здесь: https://stackoverflow.com/questions/406 ... y-instance
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»