So I read from this post from BalusC about how to stop a stateless session bean from continually thrashing a data store (e.g. DB) when accessed by JSF (which may/will make multiple calls) and so I've implemented my code in what I'd like to think is in the spirit of what was posted by BalusC (and other forums posts from "best practices" I've seen concerning this issue).
My stateless session bean looks like this:
@Stateless
@Named("productsService")
public class ProductService {
private static boolean changed = true;
private List<Product> products;
private long count;
@PersistenceContext(name = "myPU")
private EntityManager em;
@Inject
private Product product;
public ProductService() {
}
private void productRecordsFromDB() {
products = em.createNamedQuery("Product.getAll", Product.class).getResultList();
Object o = em.createNamedQuery("Product.getCount", Product.class).getSingleResult();
count = ((Long) o).longValue();
}
public void addProduct() {
synchronized (ProductService.class) {
changed = true;
em.persist(product);
}
}
public long countProducts() {
return count;
}
public void removeProduct(Product p) {
synchronized (ProductService.class) {
changed = true;
em.remove(em.merge(p));
}
}
public int removeAllProducts() {
synchronized (ProductService.class) {
changed = true;
return em.createNamedQuery("Product.deleteAll").executeUpdate();
}
}
public List<Product> getProducts() {
synchronized (ProductService.class) {
if (changed) {
productRecordsFromDB();
changed = false;
}
return products;
}
}
public Product getProduct() {
return product;
}
public void setProduct(Product p) {
product = p;
}
}
EDIT: I've added the synchronized block to the relevant portions to ensure serial access although this is now starting to feel more like a singleton. I'm still curious to know how others have dealt with this issue pertaining to multiple calls to a data store.
Specifically, I've created a 'dirty' flag that is checked and if the DB has been updated then the dirty flag is set to true (via updates to the DB). After detection of the dirty flag, it's set back to false and so only one call to the DB is made. Hence, no DB thrashing ensues.
My question is: what I've done, is this an appropriate "best practice" to solve the solution or is there a more clever way that I am not aware of? I'm kind of thinking in terms of the old 'J2EE' blue print design patterns as well as a possible annotation that I may be missing within the context of Java EE 6.