-1

I'm using spring boot and i have configured ehcache in my program. My Application Class looks like

SprinbootApplication.Class

@SpringBootApplication
@EnableJpaRepositories(basePackages = { "in.secondlevelcache.persistance"})
@EntityScan(basePackages = { "in.secondlevelcache.entity"})
@ComponentScan(basePackages = { "in.secondlevelcache.*"})
@EnableCaching
public class SpringApplicationClass  extends SpringBootServletInitializer{

@Autowired
StudentInter studentInterfaceService;

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {

    return application.sources(SpringApplicationClass.class);
}

public static void main(String args[]) throws Exception{

    SpringApplication.run(SpringApplicationClass.class, args);  
}

@Bean
public ServletRegistrationBean jerseyServlet(){
    ServletRegistrationBean register = new ServletRegistrationBean(new ServletContainer(),"/*");
    register.addInitParameter(ServletProperties.JAXRS_APPLICATION_CLASS, JerseyInitialize.class.getName());
    return register;
}

@Bean
public CacheManager getEhCacheManager(){
    return  new EhCacheCacheManager(getEhCacheFactory().getObject());
}


@Bean
public EhCacheManagerFactoryBean getEhCacheFactory(){
    EhCacheManagerFactoryBean factoryBean = new EhCacheManagerFactoryBean();
    factoryBean.setConfigLocation(new ClassPathResource("ehcache.xml"));
    factoryBean.setShared(true);
    return factoryBean;
}

@Bean
public List<Student> getAllStudentData(){
    System.out.println("Inside the GetAllStudentData of Spring Initalize");
    return studentInterfaceService.getUser();
}

Ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>

<ehcache>
<defaultCache eternal="true" maxElementsInMemory="100" overflowToDisk="false" />
<cache name="empcache" maxElementsInMemory="10" eternal="true" overflowToDisk="false" />
</ehcache>

My Interface Class

@Service
 @Cacheable("empcache")
public interface StudentInter {


public List<Student> getUser();

public List<LabelMaster> getAllLabelValue(String language);

public List<LabelMaster> getAllLocaleLabelValue();
}

My Entity Class

@Entity
@Table(name="Student")
@Access(AccessType.FIELD)
@Cacheable(value = true)
@Cache(usage=CacheConcurrencyStrategy.READ_ONLY)

public class Student {

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="roll")
private int rollId;

@Column(name="name")
private String name;

@Column(name="address")
private String address;

@Column(name="telephone")
private long phone;

public int getRollId() {
    return rollId;
}

public void setRollId(int rollId) {
    this.rollId = rollId;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getAddress() {
    return address;
}

public void setAddress(String address) {
    this.address = address;
}

public long getPhone() {
    return phone;
}

public void setPhone(long phone) {
    this.phone = phone;
}


}

I call the entity class using the repository

I call the method get user() during the server startup, i can see the query executes in my log and after that i try to call the same method by using a rest service i can see the same query fires in my log,but after that i call the same method using rest service i dint see any query

My question is 1) I load the data from db to second level cache during my server start up, then why the query is executes while I'M calling the same method using rest service ?

Aravind E
  • 1,031
  • 3
  • 15
  • 25

1 Answers1

1

First of all, you can remove all the ehcache setup since as of Spring Boot 1.3 it is auto-configured automatically. Since you are using the default "ehcache.xml" location, Spring Boot will auto-detect that and create the cache manager for you. If you are using a different location for the config, there is a property to teach Spring Boot where to find the configuration for the cache (spring.cache.ehcache.config)

Second, you can't rely on that feature in @PostConstruct as there is no way to ensure that all the post processing is already done (this is the same for pretty much every interceptors, including @Transactional for instance).

Try to move that code to afterSingletonInstantiated (from the SmartInitializingSingleton interface). If you don't want to do that, another idea is to move that code to an event listener that is invoked when the app has fully loaded:

@EventListener(ContextRefreshedEvent.class)
public void yourCacheStuff() {
   ///
}
Community
  • 1
  • 1
Stephane Nicoll
  • 31,977
  • 9
  • 97
  • 89