I've been googling and I just realized something really odd (at least to me). apparently it's recommended to set spring objects as singletons. I have several questions:
logically, it would affect performance right? if 100 users (total exaggeration) are using the same #service objects, wouldn't that mean the other 99 must queue in line to get that #service? (thus, performance issue)
what if by some diabolical design, those spring objects have states (synchronization problem)? This usually happens with ORM since the BaseDAOImpl usually have protected injected sessionfactory
speaking of injected sessionfactory, I thought annotations are not inherited? could somebody give explanation about this?
thanks
apparently it's recommended to set spring objects as singletons.
It's not necessarily recommended, but it is the default.
logically, it would affect performance right? if 100 users (total
exaggeration) are using the same #service objects, wouldn't that mean
the other 99 must queue in line to get that #service? (thus,
performance issue)
First of all, forget about users. Think about objects, threads, and object monitors. A thread will block and wait if it tries to acquire an object monitor that is owned by another thread. This is the basis of Java's synchronization concept. You use synchronization to achieve mutual exclusion from a critical section of code.
If your bean is stateless, which a #Service bean probably should be (just like a #Controller beans), then there is no critical section. No object is shared between threads using the same #Service bean. As such, there are no synchronized blocks involved and no thread waits on any other thread. There wouldn't be any performance degradation.
what if by some diabolical design, those spring objects have states
(synchronization problem)? This usually happens with ORM since the
BaseDAOImpl usually have protected injected sessionfactory
A typical design would have you use SessionFactory#getCurrentSession() which returns a Session bound to thread, using ThreadLocal. So again, these libraries are well written. There's almost always a way with which you can avoid any concurrency issue, either through ThreadLocal design as above or by playing with bean scopes.
If you can't, you should write your code so that the bottleneck is as small as possible, ie. just the critical section.
speaking of injected sessionfactory, I thought annotations are not
inherited? could somebody give explanation about this?
I'm not sure what you mean with this. You are correct that annotations are not inherited (but methods are inherited with their annotations). But that might not apply to the situation you are asking about, so please clarify.
service object being singleton doesnt mean that it has synchronised access. multple users can invoke it simultaneouly. Like a single servlet instance is used by many concurrent users in a webapplication. You only need to ensure that there is no state in your singleton object.
SessionFactory is a threaf safe object as its immutable, session is not thread safe. Ad since session factory is a heavy object, its recommended to share one session factory object per application but to use mutiple sessions.
Not clear about your 3 point, can you please elaborate a little.
Hope it helps
Related
In our application we are using Spring and Hibernate.
In all the DAO classes we have SessionFactory auto wired and each of the DAO methods are calling getCurrentSession() method.
Question I have is why not we inject Session object instead of SessionFactory object in prototype scope? This will save us the call to getCurrentSession.
I think the first method is correct but looking for concrete scenarios where second method will throw errors or may be have bad performance?
When you define a bean as prototype scope a new instance is created for each place it needs to be injected into. So each DAO will get a different instance of Session, but all invocations of methods on the DAO will end up using the same session. Since session is not thread safe it should not be shared across multiple threads this will be an issue.
For most situations the session should be transaction scope, i.e., a new session is opened when the transaction starts and then is closed automatically once the transaction finishes. In a few cases it might have to be extended to request scope.
If you want to avoid using SessionFactory.currentSession - then you will need to define your own scope implementation to achieve that.
This is something that is already implemented for JPA using proxies. In case of JPA EntityManager is injected instead of EntityManagerFactory. Instead of #Autowired there is a new #PersistenceContext annotation. A proxy is created and injected during initialization. When any method is invoked the proxy will get hold of the actual EntityManager implementation (using something similar to SessionFactory.getCurrentSession) and delegate to it.
Similar thing can be implemented for Hibernate as well, but the additional complexity is not worth it. It is much simpler to define a getSession method in a BaseDAO which internally call SessionFactory.getCurrentSession(). With this the code using the session is identical to injecting session.
Injecting prototype sessions means that each one of your DAO objects will, by definition, get it's own Session... On the other hand SessionFactory gives you power to open and share sessions at will.
In fact getCurrentSession will not open a new Session on every call... Instead, it will reuse sessions binded to the current session context (e.g., Thread, JTA Transacion or Externally Managed context).
So let's think about it; assume that in your business layer there is a operation that needs to read and update several database tables (which means interacting, directly or indirectly, with several DAOs)... Pretty common scenario right? Customarily when this kind of operation fails you will want to rollback everything that happened in the current operation right? So, for this "particular" case, what kind of strategy seems appropriate?
Spanning several sessions, each one managing their own kind of objects and bound to different transactions.
Have a single session managing the objects related to this operation... Demarcate the transactions according to your business needs.
In brief, sharing sessions and demarcating transactions effectively will not only improve your application performance, it is part of the functionality of your application.
I would deeply recommend you to read Chapter 2 and Chapter 13 of the Hibernate Core Reference Manual to better understand the roles that SessionFactory, Session and Transaction plays within the framework. It will also teach will about Units of work as well as popular session patterns and anti-patterns.
In most cases only service classes are managed by spring and are singletons. In some situations, domain code needs injection which won't work unless its managed by spring. That being said, it is advisable and non performance intensive to have all your domain classes as #bean with scope as prototype and anytime you want to do
Person p = new Person();
just do
Person p = ctx.getBean("person");
Any help on the pros and cons would be appreciated.
There is obviously more overhead in obtaining a prototype bean than simply instantiating directly via the new keyword (any dependency injection, lifecycle callbacks, etc. performed by the Spring IoC container). While likely not significant for a single instantiation, if you performed this in a loop, you could see performance issues.
If, however, you need any singleton beans (typically services) or resources (such as a DataSource), then you will prefer to use the prototype bean. Any additional dependencies will be wired in automatically.
Apart from performance considerations, your choice may also depend on your design. If you follow a "traditional" architecture with a service tier and data access objects that perist domain objects, then everything from a Spring point of view is generally stateless. Your services and data access objects are singletons using domain objects that are POJO's. Here you will rarely need a prototype bean.
If on the other hand you follow a more object-oriented approach where an object has a stateless factory (to allow instances to be fetched or created) and the object is then able to persist itself (say with a 'save' method), then nearly all your domain objects may be prototype beans.
As in nearly all decisions, there will be trade-offs and no one right answer.
As it stands I am using a JSF request scoped bean to do all my CRUD operations. As I'm sure you most likely know Tomcat doesn't provide container managed persistence so in my CRUD request bean I am using EnityManagerFactory to get fold of enity manager. Now about the validity of my choice to use request scoped bean for this task, it's probably open for a discussion (again) but I've been trying to put it in the context of what I've read in the articles you gave me links to, specifically the first and second one. From what I gather EclipseLink uses Level 2 cache by default which stored cached entity. On ExlipseLink Examples - JPA Caching website it says that:
The shared cache exists for the duration of the persistence unit ( EntityManagerFactory, or server)
Now doesn't that make my cached entities live for a fraction of time during the call that is being made to the CRUD request bean because the moment the bean is destroyed and with it EntityManagerFactory then so is the cache. Also the last part of the above sentence "EntityManagerFactory, or server" gets me confused .. what precisely is meant by or server in this context and how does one control it. If I use the #Cache annotation and set appropriate amount of expire attribute, will that do the job and keep the entities stored on the servers L2 cache than, regardless of whether my EntityManagerFactory has been destroyed ?
I understand there is a lot of consideration to do and each application has specific requirements . From my point of view configuring L2 cache is probably the most desirable (if not only, on Tomcat) option to get things optimized. Quoting from your first link:
The advantages of L2 caching are:
avoids database access for already loaded entities
faster for reading frequently accessed unmodified entities
The disadvantages of L2 caching are:
memory consumption for large amount of objects
stale data for updated objects
concurrency for write (optimistic lock exception, or pessimistic lock)
bad scalability for frequent or concurrently updated entities
You should configure L2 caching for entities that are:
read often
modified infrequently
not critical if stale
Almost all of the above points apply to my app. At the heart of it, amongst other things, is constant and relentless reading of entities and displaying them on the website (the app will serve as a portal for listing properties). There's also a small shopping cart being build in the application but the products sold are not tangible items that come as stock but services. In this case stale entities are no problem and also, so I think, isn't concurrency as the products (here services) will never be written to. So the entities will be read often, and they will be modified infrequently (and those modified are not part of the cart anyway, an even those are modified rarely) and therefore not critical if stale. Finally the first two points seem to be exactly what I need, namely avoidance of database access to already loaded entities and fast reading of frequently accessed unmodified enteties. But there is one point in disadvantages which still concerns me a bit: memory consumption for large amount of objects. Isn't it similar to my original problem?
My current understanding is that there are two options, only one of which applies to my situation:
To be able to delegate the job of longer term caching to the persistence layer than I need to have access to PersistenceContext and create a session scoped bean and set PersistenceContextType.EXTENDED. (this options doesn't apply to me, no access to PersistenceContext).
Configure the L2 #Cache annotation on entities, or like in option 1 above create a session scoped bean that will handle long term caching. But aren't these just going back to my original problem?
I'd really like to hear you opinion and see what do you think could be a reasonable way to approach this, or perhaps how you have been approaching it in your previous projects. Oh, and one more thing, just to confirm.. when annotating an entity with #Cache all linked entities will be cached along so I don't have to annotate all of them?
Again all the comments and pointers much appreciated.
Thanks for you r answer .. when you say
"In Tomcat you would be best to have some static manager that holds onto the EntityManagerFactory for the duration of the server."
Does it mean I could for example declare and initialize static EntityManagerFactory field in an application scoped been to be later used by all the beans throughout the life of the application ?
EclipseLink uses a shared cache by default. This is shared for all EntityManagers accessed from an EntityManagerFactory. You do not need to do anything to enable caching.
In general, you do not want to be creating a new EntityManagerFactory per request, only a new EntityManager. Creating a new EntityManagerFactory is quite expensive, so not a good idea, even ignoring caching (it has its own connection pool, must initialize the meta-data, etc.).
In Tomcat you would be best to have some static manager that holds onto the EntityManagerFactory for the duration of the server. Either never close it, or close it when a Servlet is destroyed.
The important technologies i use are: Glassfish v3, JSF 2.0, JPA 2.0, EclipseLink 2.0.2, log4j 1.2.16, commons-logging 1.1.1.
My problem is that some parts of the application are pretty slow. I analysed this with the netbeans 6.8 Profiling capabilities.
I. Logging - i use log4j and apache commons logging to generate logs in a logging file and in the console. The logs also appear in glassfish's server log. I use loggers as follows:
private static Log logger = LogFactory.getLog(X.class);
...
if (logger.isDebugEnabled()) {
...
logger.debug("Log...");
}
The Problem is that sometimes such short statements take much time (about 800 ms). When i switch to java.util.logging its not that bad but also very slow (200 ms band). What's the problem?
I need some logging... UPDATE - The problem with the slow logging was solved after switching from Netbeans 6.8 to Netbeans 6.9.1. - Netbeans 6.8 possibly is very slow when logs are printed to its console?! So it had nothing to do with Log4J or commons logging..
II. DB Operation:
The first time i call the find Method of the following EJB it takes 2,4 s! Additional calls last only some ms. So why takes the first operation that long? Is this (only because of) the connection establishment or has it something to do with the Dependency Injections
of the XFacade and when are these Injections performed?:
#Stateless
#PermitAll
public class XFacade {
#PersistenceContext(unitName = "de.x.persistenceUnit")
private EntityManager em;
// Other DI's
...
public List<News> find(int maxResults) {
return em.createQuery(
"SELECT n FROM News n ORDER BY n.published DESC").setMaxResults(maxResults).getResultList()
}
}
III. Dependency Injection, JNDI Lookup: Is there a difference beetween DI like (#EJB ...) and InitialContext lookups concerncing performance? Is there a difference (performance view) between injecting local, remote and no-interface EJB's?
IV. Managed Beans - I use many Session Scoped Beans, because the ViewScope seems to be very buggy and Request Scoped is not always practically. Is there an alternative? - because these Beans are not slow but the server side memory is stressed during a whole session. And when a user logs out it takes some time!
V. EJBs - I don't use MDB only Session Beans and Singleton Beans. Often they inject other Beans with the #EJB Annotation. One Singleton Bean use #Schedule Annotations to start repeatedly operations. A interesting thing i found is that since EJB 3.1 you can use the #Asynchronous Annotation to make Session Bean Method's asynchronous. What should i generally consider when implementing EJBs concerning performance?
Maybe someone could give me some general and/or specific tips to increase the performance of javaee applications, especially concerning the above issues. Thanks!
To start with, you should bench your application in a real environment using load testing tools, you can't really make valid conclusions from the behavior you observe in your IDE. On top of that don't forget that profiling actually alters performances.
I. Logging (...) The problem with the slow logging was solved after switching from Netbeans 6.8 to Netbeans 6.9.1
That's the first proof you can't use trust the behavior inside your IDE.
II. DB Operation: The first time i call the find Method of the following EJB it takes 2,4 s! Additional calls last only some ms. So why takes the first operation that long?
Maybe because some GlassFish services are (lazy) loaded, maybe because the stateless session beans (SLSB) have to be instantiated, maybe because the EntityManagerFactory has to be created. What did the profiling say? Why do you see when activating app server logging? And what's the problem since subsequent calls are ok?
III. Dependency Injection, JNDI Lookup: Is there a difference beetween DI like (#EJB ...) and InitialContext lookups concerncing performance?
JNDI lookups are expensive and it was a de facto practice to use some caching in the good old service locator. I thus don't expect the performances to be worst when using DI (I actually expect the container to be good at it). And honestly, it has never been a concern for me.
When you work on performance optimization, the typical workflow is 1) detect a slow operation 2) find the bottleneck 2) work on it 3) if the operation is still not fast enough, go back to 2). To my experience, the bottleneck is 90% of the time in the DAL. If your bottleneck is DI, you have no performance problem IMO. In other words, I think you're worrying too much and you're very close to "premature optimization".
IV. Managed Beans - I use many Session Scoped Beans, because the ViewScope seems to be very buggy and Request Scoped is not always practically. Is there an alternative? - because these Beans are not slow but the server side memory is stressed during a whole session. And when a user logs out it takes some time!
I don't see any question :) So I don't have anything to say. Update (answering a comment): Using a conversation scope might be indeed less expensive. But as always, measure.
V. EJBs - I don't use MDB only Session Beans and Singleton Beans. Often they inject other Beans with the #EJB Annotation. One Singleton Bean use #Schedule Annotations to start repeatedly operations. A interesting thing i found is that since EJB 3.1 you can use the #Asynchronous Annotation to make Session Bean Method's asynchronous. What should i generally consider when implementing EJBs concerning performance?
SLSBs (and MDBs) perform very well in general. But here are some points to keep in mind when using SLSBs:
Prefer Local over Remote interfaces if your clients and EJBs are collocated to avoid the overhead of remote calls.
Use Stateful Session Beans (SFSB) only if necessary (they are harder to use, managing state has a performance cost and they don't scale very well by nature).
Avoid chaining EJBs too much (especially if they are remote), prefer coarse grained methods over multiple fine-grained methods invocation.
Tune the SLSB pool (so that you have just enough beans to serve your concurrent clients, but not too much to avoid wasting resources).
Use transactions appropriately (e.g. use NOT_SUPPORTED for read only methods).
I would also suggest to not use something unless you really need the feature and there is a real problem to solve (e.g. #Asynchronous).
Maybe someone could give me some general and/or specific tips to increase the performance of javaee applications, especially concerning the above issues. Thanks!
Focus on your data access code, I'm pretty sure this represents 80% of the execution time of most business flows.
And as I already hinted, are you sure that you actually have a performance problem? I'm not convinced. But if you really are, measure performances outside your IDE.
I agreed with Pascal Thivent, in that "premature optimization" is bad. Design your code well, and then worry about performance.
Also, you can optimize for performance or memory-conservation. Pick which one is causing you headaches in the morning, and optimize for that.
I actually really like NetBeans' profiler; it's one of the best free ones, IMHO.
I would recommend:
Profiling for Performance but limiting the scope to either either just your own packages (e.g., de.x) or excluding Java core classes. This is so your application isn't bogged down with profiling and giving you misleading performance numbers. Basically, try to get the "Overhead" as low as possible, as indicated by the bar at the bottom.
Browse around your web app for a while see what is taking up most of your CPU time. Also take note of the fact that some objects are lazily-loaded so the first time you access pieces of code it may be slow. Also, you're using a JIT-compiler, so code may be slow the first (or second...) time you run it, but it will get faster as you use that piece of code more often. In short, use the web app for a while. You can "record" a web session using Selenium and "play" it back. This will allow you to get better performance metrics and see where your application really is slow instead of measuring "warm up time."
If there is a specific piece of code or class that is causing you trouble, use profiling points to see exactly what is causing that piece of code to be slow.
If you have a specific piece of code that's causing you problems, feel free to post about that.
The question is a bit long since it's conceptual. I hope it's not a bad read :)
I'm working in a performance critical Spring MVC/Tiles web-app (10,000 users typical load). We load an update employee screen, where we load an employee details screen (bound to an employee business object) for updates via a MultiActionController. There are multiple tabs on this screen, but only tab1 has the updatabale data. Rest of the tabs are read-only stuff, for reference basically.
Needless to say, we've decided to load these read-only tabs in a lazy manner, i.e., when each tab is activated, we fire an ajax call (one-time) for fetch the data from the server. We don't load everything via the update view loading method. Remember: this is one time, read-only data.
Now, I'm in a dilemma. I've made another multiaction controller, named "AjaxController" for handling these ajax calls. Now, my questions:
What should be the best scope for this controller?
Thoughts: If I make it request scoped, then 10,000 users together can create 10,000 instances of this bean: memory problem there. If I make it session scoped, then one will be created per user session. That means, when 10,000 users log in to the app, regardless of whether they hit the AjaxController methods, they will each have a bean in possession.
Then, is singleton the best scope for this controller?
Thoughts: A singleton bean will be created when spring boots, and this very instance will be provided throughout. Sounds good.
Should the handler methods (like fetchTab7DataInJsonFormat) be static and attached to the class?
Thoughts: In this case, can havign static methods semantically conflict with the scope? For example: does scope="session"/"request" + static methods make sense? I ask because even though each user session has its own AjaxController bean, the handler methods are actually attached to the class, and not the instances. Also, does scope="singleton" + static handler methods make sense?
Can I implement the singleton design pattern into AjaxController manually?
Thoughts: What if I control the creation: do the GoF singleton basically. Then what can the scope specification do? Scope session/request surely can't create multiple instances can they?
If, by whatever mechanism (bean specification/design pattern/static methods), I do manage to have one single instance of AjaxController: Will these STATIC methods need to be synchronized? I think not, because even if STATIC handler methods can talk to services (which talk to DB/WS/MQ etc.) which take time, I think each request thread entering the static methods will be returned by their thread Id's right? It's not like user1 enters the static method, and then user2 enters the static method before user1 has been returned, and then they both get some garbled data? This is probably silly, but I want to be sure.
I'm confused. I basically want exactly one single instance of the controller bean servicing all requests for all clients.
Critical Note: The AjaxController bean is not INJECTED anywhere else, it exists isolated. It's methods are hit via ajax calls.
If I were doing this, I would definitely make the LazyLoadController singleton without having static methods in it and without any state in it.
Also, you definitely shouldn't instantiate singletons manually, it's better to use Spring's common mechanism and let the framework control everything.
The overall idea is to avoid using any static methods and/or persistent data in controllers. The right mechanism would be use some service bean for generating data for request, so controller acts as request parameter dispatcher to fetch the data out into the view. No mutable state or concurrently unsafe stuff should be allowed in controller. If some components are user-specific, Spring's AOP system provides injection of the components based on session/request.
That's about good practice in doing thing like that. There's something to clarify to give more specific answer for your case. Did I understand it right that typical use case for will be that AjaxController will pass some of requests to LazyLoadController to get tab data? Please provide details about that in comment or your question, so I may update my answer.
The thing that is wrong with having static methods in controller is that you have to manage concurrent safety by yourself which is not just error-prone but will also reduce overall performance. Spring runs every request in its own thread, so if two concurrent calls need to use some static method and there are shared resources (so you need to use synchronize statement or locks), one of threads will have to wait for another one to complete working in protected block. From the other hand, if you use stateless services and avoid having data that may be shared for multiple calls, you get increased performance and no need to deal with concurrent data access.