I'm looking for an elegant solutions to the old problem of loading and caching static, shared data at application startup (with an infinite lifetime).
My old way was a Spring Singleton Bean, but I'm trying now to achieve it with JAVA EE 6 (JPA2, EJB3.1, CDI).
I have an @Entity
, and an @Stateless
EJB lo load the entity from database. My thought was to add a @Singleton
EJB to cache the data; I also decided to keep the original EJB separated, to prevent violating SRP (and because in the future it might be used bypassing the cache, by other actors).
Please take a look at this simplified Proof Of Concept:
Entity
@NamedQuery(name="Room.findAll", query="SELECT r FROM Room r")
@Entity
public class Room {
@Id
private Integer id; // GETTER, SETTER
private String description; // GETTER, SETTER
}
Loader
@Stateless
public class Rooms {
@PersistenceContext
EntityManager em;
public List<Room> findAll() {
return em.createNamedQuery("Room.findAll",Room.class).getResultList();
}
}
Cacher
@Singleton
public class RoomsCached {
@EJB
Rooms rooms;
private List<Room> cachedRooms; // GETTER
@PostConstruct
public void initCache(){
this.cachedRooms = Collections.unmodifiableList(rooms.findAll());
}
}
Can you see big problems, conceptual errors or something in this example ?
My main concerns were
If both were @Singleton
(mehh), I could have added @DependsOn("Rooms")
on the cacher bean, to ensure Rooms is already loaded before being used, but with @Singleton
and @Stateless
I can't... will @Stateless
bean always be loaded before CDI injects it into @Singleton
?
@Singleton
calling @Stateless
seems weird (I've seen examples of the opposite); should I change design by putting the @Singleton
instance inside the @Stateless
EJB ?
Is it right to load and cache in the @PostConstruct
method ?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…