I am using spring method level annotations #cacheable to cache the data that I fetched from database.
Can I perform caching with the above annotation at server Start up?
I tried this but it is again fetching from database not from cache.
Simply add a #PostConstruct annotation to your methods that you want to cache on server start up.
If your beans are on singleton scope, return values of methods would be cached before your application starts.
You can do this manually however, above is a very simple straightforward approach.
No. At least one request has to be made before you cache response data. That first request could either be by application user or by code itself in Post Construct as mentioned by #Pumpkin
Related
I have a class annotated with JPA #Entity annotation, so objects of this class persist in database and are managed using Hibernate ORM. In my class constructor, a connection to a MQTT broker is created, so each object during initialization stablish a TCP connection.
When a object data is fetch from the database, this constructor can not be used by the ORM, as ORM uses default constructor without arguments, so I put the code that stablish the connection in a #PostLoad annotated method.
The problem is, everytime the web application page is refreshed the ORM is asked to get the object, and the #Postload method is executed so the TCP connection is stablished again... but I want the connection to be stablished only the first time object is fetch from database, and no everytime page is refreshed.
So the solution would be a ORM with in memory object cache. This way the first time object is loaded from database the #Postload method is called, but next times ORM is asked to retrieve the object it is retrieved from cache.
I dont know if this is possible with Hibernate, I have been playing with cache options and #Cacheable annotation but it seems that #Postload method is called everytime I use the findById method of Repository class, no matter the cache options I set. So I guess Hibernate cache is caching table rows, no objects in memory.
You could use an entity manager with an extended persistence context which spans multiple transactions, but I have no idea how or if Spring Data supports this. This way, the entity would not be reloaded from the database but be part of this extended persistence context. Note though, that this comes with other issues.
Usually, such expensive operations are simply not done in entities. You could move the logic out of the class, or do some kind of connection pooling/caching to avoid reconnects. I don't know why you need a dedicated connection, but connecting to message brokers is usually done differently. Usually, such connections are pooled by some context object of the library or maybe Spring offers some integration with options for pooling. In Java/Jakarta EE, this is usually done through resource adapters. I bet there is a JMS implementation for MQTT that you could use, probably also with Spring. AFAIK, in Spring Data JPA, you usually fire a domain/application event and react to that somewhere else. In that listener you could publish a message to a topic/queue through JMS or the native MQTT library.
Consider that our application has some configs that user set them, and we need to have a backup of those data in order to restore them later.
Configs are list of different Objects and I have created some web services for each List of Object and application calls them in a chain, it means that with getting success response from one service they call the next one.
Now what the problem is...
I need to store each services data somewhere and after finishing the last service call in front end, I will create the final Object with received data from client and persist it in database(here MongoDB).
What is the best way for implementing this strategy?, consider that I don't want to persist each List of Object per service, I need to persist whole Object once.
Is there any way for storing body of a request somewhere until other services to be called?
What is the best for that?
I will appreciate any clue or solution that help me!
BEST WAY:
store all objects in client side and send only one request to server.
it reduces resource usage of server side.
ALTERNATIVE:
if you realy want to handle it by several requests (which I do not recommend it) then one strategy is : store objects of each request by an identifier related to that session (best candidate is JSESSIONID) to a temporary_objects_table and after final request store it in main tables.
and in failure of any service for that session, remove records with that sessionid from temporary_objects_table.
it has much more complexity comparing first approche.
After some research I found my answer:
REST and transaction rollbacks
and
https://stackoverflow.com/a/1390393/607033
You cannot use transactions because by REST the client maintains the client state and the server maintains the resource state. So if you want the resource state to be maintained by the client then it is not REST, because it would violate the stateless constraint. Violating the stateless constraint usually causes bad scalability. In this case it will cause bad horizontal scalability because you have to sync ongoing transactions between the instances. So please, don't try to build multi-phase commits on top of REST services.
Possible solutions:
You can stick with immediate consistency and use only a single
webservice instead of two. By resources like database, filesystem,
etc. the multi phase commit is a necessity. When you break up a
bigger REST service and move the usage of these resources into
multiple smaller REST services, then problems can occur if you do
this splitting wrongly. This is because one of the REST services will
require a resource, which it does not have access to, so it has to
use another REST service to access that resource. This will force the
multi phase commit code to move to a higher abstraction level, to the
level of REST services. You can fix this by merging these 2 REST
services and move the code to the lower abstraction level where it
belongs.
Another workaround to use REST with eventual consistency so you can
respond with 202 accepted immediately and you can process the
accepted request later. If you choose this solution then you must be
aware by developing your application that the REST services are not
always in sync. Ofc. this approach works only by inner REST services
by which you are sure that the client retry if a REST service is not
available, so if you write and run the client code.
I have no code done yet but I'm thinking on how I'm supposed to do this in JSP/JSF.
So, I have some classes I was thinking I could load from a DB whenever the session starts. My first idea is that I just load them once with the necessary data from the DB, do all the operations, and then destroy the bean when the session is done. The problem is, what if another user changes information during the session? So I thought I could use a page scope, however I don't want to overload the server.
What's the best practice on this?
Firstly, each visitor to your app gets their own session-scoped bean, so you've only got to worry about persisting each user's changes to the data on the bean.
Secondly, you are worrying about matters which are taken into consideration by ORM offerings. Using the API provided by something like Spring JPA or Hibernate will present you with controls for persisting data changes back to the DB via a local handle on a Bean.
I decided to use an application scoped bean instead of a singleton class. That will do.
I need simple, preferable session based cache, for our Spring MVC 3.1 app. I know in 3.1 introduced cashing abstraction, but as far as I know, it is application wide caching. We need something simpler, for caching user grid data. I don't mined even using it directly, as long, as it has simple interface.
Any one used something like that? Is there any good lib? Or is there way to force Spring cache abstraction to cache data for current session only? Or am I doomed to write it by myself?
Session scoped bean
If you don't mind explicit solution, create a bean with session scope and inject it to your controller.
If you don't forget to wrap it with scoped proxy (<aop:scoped-proxy/>) you can
just place your cached data in fields of that bean. Spring will automatically create one instance of that bean per each HTTP session and store it there.
Caching abstraction
On the other hand I think Spring caching abstraction might work for you - SPeL gives you access to HTTP environment so you probably construct cache key declaratively (in annotation) based on current user session id or some other attribute like user name.
I am using a JEE6 stack including JPA 2.0, JSF 2.0, EJB 3.1 etc.
The way my architecture is setup is the following:
I have JPA annotated DAOs using hibernate as my JPA provider.
I have JSF Managed beans which correspond to my facelet/xhtml pages.
I have EJBs that handle all of my database requests.
My XHTML pages have JSF EL which make calls to my Managed beans. My managed beans contain references to my DAO entities which are managed by EJBs. For example, I have a user entity which is mapped to a db table. I have a user EJB which handles all CRUD operations that return Users. I have a page that edits a user. The highlevel workflow would be: navigate to user edit page -> EL calls a method located in the managed bean that loads a user. The method calls userEJB.loadUser(user) from the EJB to get the user from the database. The user is edited and submit -> a function is called in the managed bean which calls a function in the EJB to save the user. etc.
I am running into issues accessing my data within my JSF pages using EJBs.
I am having a lot of problems with lazy initialization errors, which I believe is due to how I have set things up.
For example, I have a Client entity that has a List of users which are lazily loaded. In order to get
a client I call a method in my EJB which goes to the database, finds a client and returns it. Later on
i wish to access this clients list of users, in order to do so i have to go back to the EJB by calling some sort of method in order to load those users (since they are lazily loaded). This means that I have to create a method such as
public List<User> getUserListByClient(Client c)
{
c = em.merge(c); return c.getUserList();
}
The only purpose of this method is to load the users (and I'm not even positive this approach is good or works).
If i was doing session management myself, I would like just leave the session open for the entire request and access the property directly, this would be fine as the session would be open anyway, there seems to be this one extra layer of indirection in EJBs which is making things difficult for me.
I do like EJBs as I like the fact that they are controlled by the container, pooled, offer transaction management for free etc. However, I get the feeling that I am using them incorrectly, or I have set up my JSF app incorrectly.
Any feedback would be greatly appreciated.
thanks,
If i was doing session management
myself, I would like just leave the
session open for the entire request
and access the property directly, this
would be fine as the session would be
open anyway
Indeed, that's the open session in view pattern (also called open EntityManager in view). It can be used with EJB as well. Ideally, the transactions should be managed in the business layer/EJB so this can be seen a slight deviation from the pure layer architecture. But it solves the problem of lazy loading in the view and is easy.
Otherwise, you must make sure to eagerly load the information that will be used after the transaction is over. Or you may rely on DTO, but then it starts to be cumbersome.
Here are two more links that cover the topic and discuss pros/cons and alternatives:
SO question: Open Session In View Pattern
Xebia blog: JPA implementation patterns and especially this one
Your usage seems good. Just remember that em.merge(c) may save the changes made to Client c into the database. If you just want to get the UserList of Client c without saving the changes made to the Client c, then you can do this:
public List<User> getUserListByClient(Client c)
{
Client client = em.find(Client.class, c.clientId);
return client.getUserList();
}
Or better ,just send the Client Id to the getUserListByClient instead of passing a full Client object , just to save a tinsy winsy bit of memory :)