0

I have a method called getCustomerCount() which makes a database call to get the customer count based on the store like below.

public int getCustomerCount(String storeName) {
  return repository.getCustomerCount(storeName);
}

I need to call the above method more than once from other methods so can I use an instance variable to set the customer count the very first time this method gets called and then reuse the variable instead of calling this method and making a database call every single time? Can I do something like this:

private int customerCount;
public int getCustomerCount(String storeName) {
  int count = repository.getCustomerCount(storeName);
  customerCount = count;
  return count;
}

public void processCustomerData(String storeName) {
  getCustomerCount(storeName);
// Based on customer count, add business logic 
  sendEmail(customerList);
}

public void sendEmail(List<Customers> customers) {
// get customer count and set email count to the number of customers in the system. 
  int emailCount = 0;
  emailCount  = customerCount;
}

Would this be an issue when multiple requests execute at the same time through a rest api? Are there any pros and cons of using instance variables like this? If there are better ways than using instance variables, please suggest. I need to execute the query for each request so singleton may not work for this case. Thank you.

4
  • There are several things wrong in your code. First, you still always hit the database when calling getCustomerCount(). Second, your local variable emailCount is assigned but can't be used at all. Commented Feb 16, 2022 at 13:50
  • I always want to hit the database the first time a request has been sent to the rest api as the customer count may vary for each store. But after the first time, the data doesn't change and I want to avoid making that call until a new request comes through. Commented Feb 16, 2022 at 13:57
  • Do you really need the exact number of customers in so many occasions? If you need to loop over all the customers, just do that, without getting the number first. Commented Feb 16, 2022 at 14:02
  • private int customerCount; is not correct if this is @service, because spring-boot is singleton. you can keep the customerCount the place you call all this methods like: int customerCount = getCustomerCount(); then processCustomer(customerCount); Commented Feb 16, 2022 at 14:51

3 Answers 3

1

You could try to use the singleton design pattern for your specific problem

See this link: https://www.gofpatterns.com/creational/patterns/singleton-pattern.php

Sign up to request clarification or add additional context in comments.

4 Comments

I need to execute the query for each request and the customer count changes frequently so singleton may not work for this case.
@user3376592 if the customer count changes frequently, then why would you want to store it in a variable and avoid making database calls ?
@oaPiet I always want to hit the database the first time a request has been sent to the rest api as the customer count may vary for each store. But after the first time, the data doesn't change and I want to avoid making that call until a new request comes through.
@user3376592 please, clarify your problem and infrastructure, unifies the information of the comments and add them to your post for helping you.
0

I assume code above you shared is customerService. SpringBoot is singleton, so it is not good practice to have global variables(if they are not constant) in SpringBoot objects.

@Service
private CustomerService customerService;

int customerCount = customerService.getCustomerCount();
customerService.processCustomer(customerCount); // you should pass customerCount

Also you should change sendEmail method as it should take customerCount as argument if customers size can be different from customerCount

public void sendEmail(List<Customers> customers, int customerCount)

Comments

0

If you don't want the method to hit the database each time, you should use the Integer wrapping class and store the count in a map:

private Map<String, Integer> customerCountMap = new HashMap();
public int getCustomerCount(String storeName) {
  if(customerCountMap.get(storeName) == null) {
    // you will probably need to pass the store name to the repository...
    customerCountMap.put(storeName, repository.getCustomerCount(storeName));
  }
  return customerCountMap.get(storeName);
}

You still need to update the count on Insert and delete. So you might end up with Spring caching anyway (or you could use the old fashioned observer pattern).

The sendEmail() method still doesn't make sense.

6 Comments

If I use the integer wrapping mechanism, if multiple calls are made to the rest api, would that be a problem? Let's say when the first request comes through, the customerCount is set to 10 and when a second request comes at the same time, would the count be still set to 10? I want every new request to make a new database call. Can you please clarify?
YOU have to clarify your infrastucture and your use case, I think my 5 lines are easy to understand.
There is a parameter sent in the request to distinguish each stores. So there will be a parameter inside getCustomerCount(String storeName) and the database call gets the customer count based on the store name. Sorry I didn't specify it clearly. My goal is not to make the database call more than once in each request. Also I want to make sure that the variable value gets overridden for each subsequent requests.
You should update your question with the informations you provide piece by piece in comments. Otherwise it's hard to bring question and answer together.
Updated. Let me know if this is helpful.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.