patrones patron ejercicios diseño conexion java java-ee jpa singleton ejb

java - patron - Datos de ámbito de aplicaciones LOAD y CACHE con @Singleton y @Stateless



singleton c# (1)

Bueno, hice algunas pruebas y también probé el modo @Decorator . Este todavía parece ser el mejor.

@Entity bean y @Stateless bean son lo mismo de la pregunta, mientras que he cambiado el @Singleton bean de la siguiente manera, agregando también el clásico caché temporizado:

@Singleton public class RoomsCached { @Inject Rooms rooms; private List<Room> cachedRooms; private long timeout = 86400000L; // reload once a day private long lastUpdate; public List<Room> getCachedRooms() { initCache(); return cachedRooms; } public void initCache() { if (cachedRooms == null || expired()) { cachedRooms = Collections.unmodifiableList(rooms.findAll()); lastUpdate = System.currentTimeMillis(); } } private boolean expired() { return System.currentTimeMillis() > lastUpdate + timeout; } }

No es necesario @PostConstruct, ni a @EJB, no hay problemas de sincronización con el bean subyacente, @ inject-ed @Stateless.

Está funcionando bien.

Estoy buscando soluciones elegantes al viejo problema de cargar y almacenar en caché datos estáticos y compartidos al inicio de la aplicación (con una vida útil infinita).

Mi antigua forma era Spring Singleton Bean, pero ahora estoy tratando de lograrlo con JAVA EE 6 (JPA2, EJB3.1, CDI).

Tengo un @Entity , y un @Stateless EJB lo carga la entidad desde la base de datos. Mi idea era agregar un @Singleton EJB para almacenar en caché los datos; También decidí mantener el EJB original separado, para evitar la violación de SRP (y porque en el futuro podría ser usado pasando el caché, por otros actores).

Por favor, eche un vistazo a esta prueba de concepto simplificada:

Entidad

@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 }

Cargador

@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()); } }

¿Puedes ver grandes problemas, errores conceptuales o algo en este ejemplo?

Mis principales preocupaciones fueron

  1. Si ambos fueran @Singleton (mehh), podría haber agregado @DependsOn("Rooms") en el bean cacher, para asegurar que Rooms ya esté cargado antes de ser utilizado, pero con @Singleton y @Stateless no puedo ... will @Stateless bean siempre se carga antes de que CDI lo inyecte en @Singleton ?

  2. @Singleton llamando a @Stateless parece extraño (he visto ejemplos de lo contrario); ¿Debo cambiar el diseño colocando la instancia de @Singleton dentro del @Stateless EJB?

  3. ¿Es correcto cargar y almacenar en caché el método @PostConstruct ?