У меня есть следующий метод, который вызывает два репозитория jpa для удаления некоторых кортежей. Очевидно, они должны быть аннотированы с помощью пружинной аннотации @Transactional.
@Override
@Transactional
public void deleteBasket(Long id)
{
basketJpaRepository.deleteById(id);
slaSpecificationJpaRepository.deleteByBasketId(id);
}
Когда я запускаю свои тесты, я получаю очень странную ошибку StackMap:
Caused by: java.lang.IllegalStateException: Unable to load cache item
at org.springframework.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:79)
at org.springframework.cglib.core.internal.LoadingCache.get(LoadingCache.java:34)
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:134)
at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:319)
at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:569)
at org.springframework.cglib.proxy.Enhancer.createClass(Enhancer.java:416)
at org.springframework.aop.framework.ObjenesisCglibAopProxy.createProxyClassAndInstance(ObjenesisCglibAopProxy.java:58)
at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:205)
... 113 more
Caused by: java.lang.VerifyError: Stack map does not match the one at exception handler 16
Exception Details:
Location:
com/scotiacapital/slopoke/persistence/service/BasketJpaService$$EnhancerBySpringCGLIB$$68de802a.<init>(Lcom/scotiacapital/slopoke/persistence/repository/BasketJpaRepository;Lcom/scotiacapital/slopoke/persistence/repository/SLASpecificationJpaRepository;Lcom/scotiacapital/slopoke/persistence/mapper/ClientConfigMapper;Lcom/scotiacapital/slopoke/persistence/service/IBasketIdGenerationService;Lcom/scotiacapital/slopoke/validation/BasketValidator;)V @16: athrow
Reason:
Current frame's flags are not assignable to stack map frame's.
Current Frame:
bci: @0
flags: { flagThisUninit }
locals: { uninitializedThis, 'com/scotiacapital/slopoke/persistence/repository/BasketJpaRepository', 'com/scotiacapital/slopoke/persistence/repository/SLASpecificationJpaRepository', 'com/scotiacapital/slopoke/persistence/mapper/ClientConfigMapper', 'com/scotiacapital/slopoke/persistence/service/IBasketIdGenerationService', 'com/scotiacapital/slopoke/validation/BasketValidator' }
stack: { 'java/lang/RuntimeException' }
Stackmap Frame:
bci: @16
flags: { }
locals: { top, 'com/scotiacapital/slopoke/persistence/repository/BasketJpaRepository', 'com/scotiacapital/slopoke/persistence/repository/SLASpecificationJpaRepository', 'com/scotiacapital/slopoke/persistence/mapper/ClientConfigMapper', 'com/scotiacapital/slopoke/persistence/service/IBasketIdGenerationService', 'com/scotiacapital/slopoke/validation/BasketValidator' }
stack: { 'java/lang/Throwable' }
Bytecode:
0000000: 2a59 2b2c 2d19 0419 05b7 0150 b800 38b1
0000010: bfbb 004e 5a5f b700 51bf
Exception Handler Table:
bci [0, 16] => handler: 16
bci [0, 16] => handler: 16
bci [0, 16] => handler: 17
Stackmap Table:
full_frame(@16,{Top,Object[#338],Object[#340],Object[#342],Object[#344],Object[#346]},{Object[#76]})
same_locals_1_stack_item_frame(@17,Object[#76])
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:416)
at org.springframework.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:563)
at org.springframework.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:363)
at org.springframework.cglib.proxy.Enhancer.generate(Enhancer.java:582)
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:110)
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:108)
at org.springframework.cglib.core.internal.LoadingCache$2.call(LoadingCache.java:54)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at org.springframework.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:61)
... 120 more
Что делает "Причина: java .lang.VerifyError: Карта стека не совпадает с той, что у обработчика исключений 16 "означает? Как я могу это исправить?
РЕДАКТИРОВАТЬ:
Это мои зависимости:
dependencies {
compile group: 'org.springframework', name: 'spring-core', version: '5.2.3.RELEASE'
compile group: 'org.springframework.data', name: 'spring-data-elasticsearch', version: '3.2.3.RELEASE'
implementation 'org.springframework.boot:spring-boot-starter-json'
implementation 'org.springframework.boot:spring-boot-starter-web'
runtimeOnly 'org.springframework.boot:spring-boot-devtools'
compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'com.h2database:h2'
// lombok
annotationProcessor('org.projectlombok:lombok')
compileOnly('org.projectlombok:lombok')
testAnnotationProcessor('org.projectlombok:lombok')
testCompileOnly('org.projectlombok:lombok')
// --- Test Dependencies ---
testCompile('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit'
exclude group: "com.vaadin.external.google", module: "android-json"
}
testCompile(group: 'org.mockito', name: 'mockito-junit-jupiter', version: '2.23.0')
testCompile(group: 'org.hamcrest', name: 'hamcrest', version: '2.1')
// JUnit Platform Support
testCompile "org.junit.jupiter:junit-jupiter-api:$jupiterVersion"
testCompile "org.junit.jupiter:junit-jupiter-params:$jupiterVersion"
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$jupiterVersion"
// Mapstruct
compile 'org.mapstruct:mapstruct:1.3.1.Final'
annotationProcessor "org.mapstruct:mapstruct-processor:1.3.1.Final"
// Swagger
compile group: 'io.springfox', name: 'springfox-swagger2', version: '2.9.2'
compile group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.9.2'
// Kafka
compile (group: 'org.springframework.kafka', name: 'spring-kafka', version: '2.4.1.RELEASE') {
exclude group: 'org.slf4j', module: 'slf4j-log4j12'
}
compile('io.confluent:kafka-streams-avro-serde:3.3.0') {
exclude group: 'org.slf4j', module: 'slf4j-log4j12'
}
// compile group: 'io.confluent', name: 'kafka-avro-serializer', version: '5.4.0'
// compile (group: 'io.confluent', name: 'kafka-schema-registry', version: '5.4.0') {
// exclude group: 'org.slf4j', module: 'slf4j-log4j12'
// }
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.10.2'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.10.2'
// Streaming
compile group: 'org.apache.kafka', name: 'kafka-streams', version: '2.4.0'
compile group: 'org.apache.kafka', name: 'kafka-clients', version: '2.4.0'
compile group: 'org.springframework', name: 'spring-messaging', version: '5.2.3.RELEASE'
//ES
compile group: 'org.elasticsearch.client', name: 'elasticsearch-rest-client', version: '7.6.0'
compile group: 'org.elasticsearch.client', name: 'elasticsearch-rest-high-level-client', version: '7.6.0'
compile group: 'org.elasticsearch', name: 'elasticsearch', version: '7.6.0'
compile group: 'org.elasticsearch.plugin', name: 'aggs-matrix-stats-client', version: '7.6.0'
implementation 'com.cronutils:cron-utils:9.0.2'
}
Это мой класс обслуживания:
package com.scotiacapital.slopoke.persistence.service;
import com.scotiacapital.slopoke.exception.InvalidBasketException;
import com.scotiacapital.slopoke.domain.Basket;
import com.scotiacapital.slopoke.domain.OutboundTicket;
import com.scotiacapital.slopoke.persistence.repository.BasketJpaRepository;
import com.scotiacapital.slopoke.persistence.repository.SLASpecificationJpaRepository;
import com.scotiacapital.slopoke.persistence.dto.BasketJpaDto;
import com.scotiacapital.slopoke.persistence.dto.CompletenessSLASpecificationJpaDto;
import com.scotiacapital.slopoke.persistence.dto.ProcessingTimeSLASpecificationJpaDto;
import com.scotiacapital.slopoke.persistence.dto.TimelinessSLASpecificationJpaDto;
import com.scotiacapital.slopoke.persistence.mapper.ClientConfigMapper;
import com.scotiacapital.slopoke.sla.specs.CompletenessSLASpecification;
import com.scotiacapital.slopoke.sla.specs.ProcessingTimeSLASpecification;
import com.scotiacapital.slopoke.sla.specs.TimelinessSLASpecification;
import com.scotiacapital.slopoke.utils.StreamUtils;
import com.scotiacapital.slopoke.validation.BasketValidator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
@Service
public class BasketJpaService implements IBasketService
{
private final BasketJpaRepository basketJpaRepository;
private final SLASpecificationJpaRepository slaSpecificationJpaRepository;
private final ClientConfigMapper clientConfigMapper;
private final IBasketIdGenerationService basketIdGenerator;
private final BasketValidator basketValidator;
public BasketJpaService(BasketJpaRepository basketJpaRepository, SLASpecificationJpaRepository slaSpecificationJpaRepository, ClientConfigMapper clientConfigMapper, IBasketIdGenerationService basketIdGenerator, BasketValidator basketValidator)
{
this.basketJpaRepository = basketJpaRepository;
this.slaSpecificationJpaRepository = slaSpecificationJpaRepository;
this.clientConfigMapper = clientConfigMapper;
this.basketIdGenerator = basketIdGenerator;
this.basketValidator = basketValidator;
}
@Override
public Map<String, List<Basket>> getSubSystemBasketMapping(String systemId)
{
List<BasketJpaDto> baskets = this.basketJpaRepository.getBasketsBySystemId(systemId);
Map<String, List<Basket>> subSystemBasketMapping = new HashMap<>();
for (BasketJpaDto basketJpaDto : baskets)
{
Basket basket = clientConfigMapper.mapFromPersistenceLevelToDomainLevel(basketJpaDto);
Map<Class<? extends CompletenessSLASpecification>, ? extends List<? extends CompletenessSLASpecification>> slaMapping = getSLASpecMapping(basketJpaDto);
putSLASpecsIntoBasket(basket, slaMapping);
subSystemBasketMapping
.computeIfAbsent(basket.getSubSystemId(), k -> new ArrayList<>())
.add(basket);
}
return subSystemBasketMapping;
}
@SuppressWarnings("unchecked")
private void putSLASpecsIntoBasket(Basket basket, Map<Class<? extends CompletenessSLASpecification>, ? extends List<? extends CompletenessSLASpecification>> slaJpaMapping)
{
basket.setCompletenessSLASpecifications((List<CompletenessSLASpecification>) slaJpaMapping.get(CompletenessSLASpecification.class));
basket.setTimelinessSLASpecifications((List<TimelinessSLASpecification>) slaJpaMapping.get(TimelinessSLASpecification.class));
basket.setProcessingTimeSLASpecifications((List<ProcessingTimeSLASpecification>) slaJpaMapping.get(ProcessingTimeSLASpecification.class));
}
private Map<Class<? extends CompletenessSLASpecification>, List<CompletenessSLASpecification>> getSLASpecMapping(BasketJpaDto b)
{
List<? extends CompletenessSLASpecificationJpaDto> slaSpecificationDtos = slaSpecificationJpaRepository.getAllByBasketId(b.getBasketId());
Map<Class<? extends CompletenessSLASpecification>, List<CompletenessSLASpecification>> slaMapping = new HashMap<>();
for (CompletenessSLASpecificationJpaDto jpaDto : slaSpecificationDtos)
{
if (jpaDto instanceof TimelinessSLASpecificationJpaDto)
{
TimelinessSLASpecification timelinessSLASpecification = clientConfigMapper.mapFromPersistenceLevelToDomainLevel((TimelinessSLASpecificationJpaDto) jpaDto);
slaMapping.computeIfAbsent(TimelinessSLASpecification.class, k -> new ArrayList<>()).add(timelinessSLASpecification);
} else if (jpaDto instanceof ProcessingTimeSLASpecificationJpaDto)
{
ProcessingTimeSLASpecification processingTimeSLASpecification = clientConfigMapper.mapFromPersistenceLevelToDomainLevel((ProcessingTimeSLASpecificationJpaDto) jpaDto);
slaMapping.computeIfAbsent(ProcessingTimeSLASpecification.class, k -> new ArrayList<>()).add(processingTimeSLASpecification);
} else
{
CompletenessSLASpecification completenessSLASpecification = clientConfigMapper.mapFromPersistenceLevelToDomainLevel(jpaDto);
slaMapping.computeIfAbsent(CompletenessSLASpecification.class, k -> new ArrayList<>()).add(completenessSLASpecification);
}
}
return slaMapping;
}
@Override
public OutboundTicket<Long, Basket> acceptBasket(Basket basket) throws InvalidBasketException
{
OutboundTicket<Long, Basket> outboundTicket = new OutboundTicket<>();
basketValidator.validate(basket);
Long id = basketIdGenerator.generateId();
Basket persistedBasket = persistBasket(basket, id);
outboundTicket.setSuccess(persistedBasket, id);
return outboundTicket;
}
@Override
@Transactional
public void deleteBasket(Long id)
{
basketJpaRepository.deleteById(id);
slaSpecificationJpaRepository.deleteByBasketId(id);
}
private Basket persistBasket(Basket basket, Long id)
{
BasketJpaDto basketJpaDto = clientConfigMapper.mapFromDomainLevelToPersistenceLevel(basket);
basketJpaDto.setBasketId(id);
basketJpaRepository.save(basketJpaDto);
List<CompletenessSLASpecificationJpaDto> completenessSLASpecificationJpaDtos = clientConfigMapper.mapFromDomainToPersistenceLevelCompleteness(basket.getCompletenessSLASpecifications());
List<TimelinessSLASpecificationJpaDto> timelinessSLASpecificationJpaDtos = clientConfigMapper.mapFromDomainToPersistenceTimeliness(basket.getTimelinessSLASpecifications());
List<ProcessingTimeSLASpecificationJpaDto> processingTimeSLASpecifications = clientConfigMapper.mapFromDomainToPersistenceLevelProcessingTime(basket.getProcessingTimeSLASpecifications());
StreamUtils
.fromListsNullSafe(completenessSLASpecificationJpaDtos, timelinessSLASpecificationJpaDtos, processingTimeSLASpecifications)
.peek(item -> item.setBasketId(id))
.forEach(slaSpecificationJpaRepository::save);
return basket;
}
}