0

I'm using springboot and echCache3 in order to keep in memory some parameters. I have configured in this way :

echcache.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://www.ehcache.org/v3"
    xmlns:jsr107="http://www.ehcache.org/v3/jsr107"
    xsi:schemaLocation="
            http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.0.xsd
            http://www.ehcache.org/v3/jsr107 http://www.ehcache.org/schema/ehcache-107-ext-3.0.xsd">

    <cache alias="paramCache">
       

        <listeners>
            <listener>
                <class>com.telefonica.npro.cacheconf.CacheEventLogger</class>
                <event-firing-mode>ASYNCHRONOUS</event-firing-mode>
                <event-ordering-mode>UNORDERED</event-ordering-mode>
                <events-to-fire-on>CREATED</events-to-fire-on>
                <events-to-fire-on>EXPIRED</events-to-fire-on>
            </listener>
        </listeners>

      <resources>
      <heap unit="entries">2000</heap> 
      <offheap unit="MB">100</offheap> 
    </resources>
    </cache>

</config>

CacheConfig

@Configuration
@EnableCaching
public class CacheConfig {
 
}

CacheEventLogger

public class CacheEventLogger implements CacheEventListener<Object, Object> {

    private static final Logger log = LogManager.getLogger(CacheEventLogger.class);

    @Override
    public void onEvent(CacheEvent<Object, Object> cacheEvent) {
        log.info("Cache event {} for item with key {}. Old value = {}, New value = {}", cacheEvent.getType(), cacheEvent.getKey(), cacheEvent.getOldValue(), cacheEvent.getNewValue());
    }


}

And I'm using it on CustomRepositoryImpl

    public class CustomRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID>
        implements CustomRepository<T, ID> {

....

    @Override
    @Transactional
    @Cacheable(value = "paramCache")
    public String getParam(String nombreParametro) {
        String valor = (String) entityManager
                .createNativeQuery(
                        "Select valor from npro_configuracion where parametro='" + nombreParametro + "' and activo='S'")
                .getSingleResult();
        return valor;
    }
..
}

But I dont see any trace of the CacheEventLogger, and everytime I ask for the value is doing the query... What is wrong?

EDIT (adding more info)

This is the class where I'm calling the getParam method. It's @Service class..

@Service("uorganizativaService")
@Transactional
public class UOrganizativaServiceImpl implements UOrganizativaService {
...
    @Override
public List<UnidadOrganizativaDTO> getUOrganizativaFiltered(String id_centro_coste, String nombre_centro_coste,
        String id_orden_interna) {

    TSpecification<UnidadOrganizativa> uorganizativadSpecification = new TSpecification<UnidadOrganizativa>();

    if (nombre_centro_coste != null && !nombre_centro_coste.isEmpty() && !nombre_centro_coste.equals("null")) {
        logger.debug("Filtramos por el campo nombre_centro_coste = " + nombre_centro_coste);
        uorganizativadSpecification
                .add(new SearchCriteria("nombre_centro_coste", nombre_centro_coste, SearchOperation.MATCH_END));
    }
    if (id_centro_coste != null && !id_centro_coste.isEmpty() && !id_centro_coste.equals("null")) {
        logger.debug("Filtramos por el campo id_centro_coste = " + id_centro_coste);
        uorganizativadSpecification
                .add(new SearchCriteria("id_centro_coste", id_centro_coste, SearchOperation.MATCH_END));
    }
    if (id_orden_interna != null && !id_orden_interna.isEmpty() && !id_orden_interna.equals("null")) {
        logger.debug("Filtramos por el campo id_orden_interna = " + id_orden_interna);
        uorganizativadSpecification
                .add(new SearchCriteria("id_orden_interna", id_orden_interna, SearchOperation.MATCH_END));
    }
    uorganizativadSpecification.add(new SearchCriteria("activo", "S", SearchOperation.EQUAL));

    Pageable topfifty = new PageRequest(0, 50);
    Page<UnidadOrganizativa> listaUorganizativa = uorganizativaRepository.findAll(uorganizativadSpecification,
            topfifty);

    String totalRegistrosMostrar =  uorganizativaRepository.getParam("MAX_REGISTROS_A_MOSTRAR");
    //Total de elementos
    long totalRegistrosBD = listaUorganizativa.getTotalElements();
    List<UnidadOrganizativa> lista = listaUorganizativa.getContent();
    // Indicador para advertir si mostramos todos los registros o no
    boolean registrosLimitados = totalRegistrosBD > Integer.valueOf(totalRegistrosMostrar) ? true : false;
    List<UnidadOrganizativaDTO> listaUOrganizativaDTO = lista.stream().map(e -> new UnidadOrganizativaDTO(e,registrosLimitados))
            .collect(Collectors.toList());
    


    return listaUOrganizativaDTO;
}

Regards

Antonio Diaz
  • 133
  • 1
  • 1
  • 14
  • 1
    Firstly I think you should introduce this into your application.properties file spring.cache.jcache.config=classpath:ehcache.xml secondly if you are using the cache listener just to debug and log cache operations you don't need them. You can enable traces to see the cache operations with this one logging.level.org.springframework.cache=TRACE – cool Jun 28 '20 at 10:06
  • Hello, it is already added. The problem is using @cacheable on Repository, I did a test in other method but in Service, and it's running. Are there any problem to use this on the repository? I think is usefull in this way instead of create a service and model just for the parameters – Antonio Diaz Jun 28 '20 at 10:14
  • can you also share how you are calling this repository method like from which class? – cool Jun 28 '20 at 10:16
  • Edited adding the info, as you see I'm calling from service class. UOrganizativaRepository exten from CustomRepository and JPARepository – Antonio Diaz Jun 28 '20 at 10:25
  • I don't see any call to "getParametro" method – cool Jun 28 '20 at 10:29
  • I'm sorry, I copied wrong, but the method in CustomRepositoryImpl is named getParam, I edited it – Antonio Diaz Jun 28 '20 at 10:31
  • I asked just to make sure the code can actually use the cachable annotation by initiating the call from outside of class so that it can use the proxy. It looks like everything is ok. I still recommend to enable tracing and check the logs. Because it can give you some useful insight. – cool Jun 28 '20 at 10:35
  • Sorry but I'm a new on springboot and hibernate and I dont know how to do that. Could you show me how to do it? – Antonio Diaz Jun 28 '20 at 13:19
  • Do you have a file "application.properties" or "application.yml"? if not create one in your src/main/resources directory and add this line to it "logging.level.org.springframework.cache=TRACE". That is it should start seeing the logs for the cache operation in the logs. – cool Jun 28 '20 at 13:32
  • I'm not getting any log, however, if I include the @cacheable annotation to any other method in service, it is working for that info and I'm getting the logs about cache. The issue is using it on repository method – Antonio Diaz Jun 28 '20 at 13:40

1 Answers1

0

I solved already changin the @Cacheable annotation from the Impl to the Interface.

    @NoRepositoryBean
public interface CustomRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {
 ....

    @Cacheable(value = "paramCache")
    String getParam(String nombreParametro);
}
Antonio Diaz
  • 133
  • 1
  • 1
  • 14