0

I have suddently found that @Cacheable not worked when i call cacheable method from method inside not bean class.

Please find below my code and help me what is issue or something i miss.

EmployeeDAO.java

@Component("employeeDAO")
public class EmployeeDAO {
private static EmployeeDAO staticEmployeeDAO;

public static EmployeeDAO getInstance(){
    return staticEmployeeDAO;
}

@PostConstruct
void initStatic(){
    staticEmployeeDAO = this;
}

@Cacheable(value = "employeeCache")
public List<Employee> getEmployees() {
    Random random = new Random();
    int randomid = random.nextInt(9999);
    System.out.println("*** Creating a list of employees and returning the list ***");
    List<Employee> employees = new ArrayList<Employee>(5);
    employees.add(new Employee(randomid, "Ben", "Architect"));
    employees.add(new Employee(randomid + 1, "Harley", "Programmer"));
    employees.add(new Employee(randomid + 2, "Peter", "BusinessAnalyst"));
    employees.add(new Employee(randomid + 3, "Sasi", "Manager"));
    employees.add(new Employee(randomid + 4, "Abhi", "Designer"));
    return employees;
}    

MyThread.java

class MyThread{
public void run(){
    //How to get Employee data. ?????
}
}    

UtilityClass.java

public class UtilityClass {
public static void getEmployee(){
    EmployeeDAO.getInstance().getEmployees();
}
}    

Main.java

public class Main {


public static void main(String[] args) {

    ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
    EmployeeDAO dao = (EmployeeDAO)context.getBean("employeeDAO");

    System.out.println("1'st call");
    dao.getEmployees();
    System.out.println("2'nd call");
    dao.getEmployees();
    System.out.println("Call cache method using utility class");

    System.out.println("1'st call on utilityclass");
    UtilityClass.getEmployee();
    System.out.println("2'nd call on utilityclass");
    UtilityClass.getEmployee();
}
}    

Output :

1'st call
*** Creating a list of employees and returning the list ***
2'nd call
Call cache method using utility class
1'st call on utilityclass
*** Creating a list of employees and returning the list ***
2'nd call on utilityclass
*** Creating a list of employees and returning the list ***  

Can any one help me ?

Kamlesh Kanazariya
  • 1,209
  • 2
  • 15
  • 32
  • Check this: http://stackoverflow.com/a/12116107/4178025 – Diego Jan 29 '15 at 12:58
  • It is the same problem and solution I have described here http://stackoverflow.com/questions/28165943/spring-aspect-logger/28167952#28167952 – Ralph Jan 29 '15 at 13:13

1 Answers1

2

Spring uses proxies to apply AOP, however proxies are created after a bean has been constructed.

In your @PostConstruct annotated method you are setting a reference to this however at that moment that is the unproxied instance of the bean. You really need the proxied instance.

I would also note that your solution is imho a very bad one and wouldn't pass my QA check. but that is imho.

M. Deinum
  • 115,695
  • 22
  • 220
  • 224
  • @Denium How can i get data from database inside my utility class or thread which are not bean? I don't to make bean my thread – Kamlesh Kanazariya Jan 29 '15 at 13:34
  • Find a way to obtain the context, retrieve the bean and use it. However I would argue that what you try to do is a good solution... A static method to retrieve data... Looks like you are trying to invent your own caching layer. – M. Deinum Jan 29 '15 at 13:38
  • @Deinum Thanks for help, Currently i am troubling to get data in my thread class , so can you suggest and share code for retrieve employee data on my thread. Is good way to get context and get bean from that inside every my thread class? – Kamlesh Kanazariya Jan 29 '15 at 13:43
  • Why aren't you just injecting the service into your class. Why the ugly static stuff. – M. Deinum Jan 29 '15 at 14:04
  • @Deinum Please forgot static stuff but what about thread class. How can i inject service class in my thread because my thread is not a bean? – Kamlesh Kanazariya Jan 29 '15 at 14:08
  • Then make it a bean. I don't see the problem. What is it you want to achieve with that thread (generally that is something you want to avoid and just do some scheduling when messing around with threads yourself). – M. Deinum Jan 29 '15 at 14:14
  • @Deinum Can you give me solution of this problem [http://programmers.stackexchange.com/questions/271532/best-way-to-get-data-from-database-inside-thread-class-in-spring] – Kamlesh Kanazariya Jan 29 '15 at 14:20
  • @Deinum How to get employee data on MyThread class , please see on my question that MyThread class i have added. – Kamlesh Kanazariya Jan 29 '15 at 14:30
  • The question already has a comment which is a solution. But as I mentioned make it a bean, scope prototype and each time you need an instance retrieve one from the application context. But as stated you shouldn't be messing around with threads in the first place imho especially not in an app server (at some point it will turn its back and bite you). – M. Deinum Jan 29 '15 at 14:40