Spring Boot и Hibernate вызывают несколько раз один и тот же метод - PullRequest
0 голосов
/ 03 мая 2018

У меня странное поведение с Spring Boot и Hibernate. Я называю метод и Spring в некоторых случаях, когда его называют несколько раз. Вот пример лога на Tomcat:

2018-05-03 15:10:26.661 ERROR 4309 --- [nio-8009-exec-7] i.c.edile.service.api.ApiServiceImpl     : Api Service Get Fattura By Commessa: 248 
.............. 
2018-05-03 15:11:06.468 ERROR 4309 --- [io-8009-exec-10] i.c.edile.service.api.ApiServiceImpl     : Api Service Get Fattura By Commessa: 248 
.............. 
018-05-03 15:11:55.115 ERROR 4309 --- [nio-8009-exec-8] i.c.edile.service.api.ApiServiceImpl     : Api Service Get Fattura By Commessa: 248 
.............. 
2018-05-03 15:11:57.942 ERROR 4309 --- [io-8009-exec-11] i.c.edile.service.api.ApiServiceImpl     : Api Service Get Fattura By Commessa: 248

Я перехватываю запрос следующим способом внутри контроллера:

@GetMapping(value="/concludi")
public void concludi() {
    apiService.concludiCommessa();
}

Этот метод вызывает сервис:

@Service("apiService")
public class ApiServiceImpl implements ApiService{

    @Override
    public void concludiCommessa() {

        try {
            for(Commessa c : commessaRepository.findCommessaDaConcludere()) {
                String ftt = keycloakRestTemplate.getForEntity(URL), String.class).getBody();
                if(ftt == null) {
                    continue;
                }
            //........
        } catch (RestClientException | IOException e) {
            LOG.error("Api Service Get Fattura By Commessa: {}", e.getMessage());
        }
    }

}

По сути, для каждого элемента, который репозиторий возвращает службе, я использую KeycloackRestTemplate для вызова другого веб-приложения.

Это метод внутри контроллера, который перехватывает вызов с использованием шаблона rest:

@GetMapping(value="/concludiCommessa", params="num", produces="application/json")
    public FatturaCommessaDto concludiCommessa(@RequestParam(value="num", required=true) final String numeroCommessa){
        return fattureService.findByNumeroCommessa(numeroCommessa);
    }

Это метод внутри службы:

@Service(value="fatturaService")
@Transactional
public class FatturaServiceImpl implements FatturaService {

    @PersistenceContext(unitName="persistenceUnitI24")
    private EntityManager emI24;

    @Override
        public FatturaCommessaDto findByNumeroCommessa(String numeroCommessa) {
            Session session = emI24.unwrap(Session.class);
            FatturaI24 fattureI24 = (FatturaI24) session.createQuery("select f from FatturaRighe r join r.idFatturaI24 f join r.nota n where n.nota like '%"+numeroCommessa+"%'")
             .setCacheMode(CacheMode.IGNORE)
             .uniqueResult();

            //some code
        }

Проблема заключается в том, что Spring дублирует вызов для каждого элемента, извлеченного из apiService, поэтому через некоторое время Tomcat теряет соединение с БД, поскольку существует много соединений.

Почему это происходит?

Ответы [ 2 ]

0 голосов
/ 16 мая 2018

Я решил эту проблему.

В моем случае проблема заключалась в Sql Server. Я просто увеличил объем памяти для запроса, и после этого он работал отлично. Я также использовал репозиторий, как предложил @SAM.

0 голосов
/ 03 мая 2018

Обычно это происходит, когда вы аннотируете класс как @Service и имеете функции, которые должны быть в классе Дао с аннотацией @Repository.

Поток должен быть: Контроллер -> Сервис -> Хранилище.

Вместо того, чтобы обращаться к БД напрямую из класса Service, введите DAO с аннотацией @Repository, и это должно потренировать.

OR

добавить аннотацию @Repository к ApiServiceImpl. Однако это не очень хорошая практика.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...