There has been a similar thread here already (
https://groups.google.com/forum/#!searchin/google-guice/Should$20Guice-Injected$20DAO$27s$20be$20Singletons$3F/google-guice/3B8XrwB-p18/B6OF13HWRnEJ) but I don't think it has received a satisfying answer yet.
The baseline:
We are using Guice in a JSF/Primefaces webapplication running on Tomcat. Persistence is handled via JPA/Hibernate.
Right now ALL our DAOs (approx. one per Entity) are annotated as @Singleton. The only reason for this seem to be performance concerns as another (non JSF but Webservice) part of the application will receive thousands of hits per seconds and our main developer believes, that constructing a DAO Singleton once and then getting it in a synchronized way is cheaper than to always inject a new instance (which is the Guice Default Scope).
This goes contrary to what the Google Guice Wiki writes about Scopes: If the object is
stateless and
inexpensive to create, scoping is unnecessary. Leave the binding unscoped and Guice will create new instances as they're required...Although singletons save object creation (and later garbage collection),
initialization of the singleton requires synchronization; ...
Now, what exactly does "initialization of the singleton" mean in this context? Is initialization done once? Everytime it is injected?
Is the assumption correct that, with the above scenario (thousands of
hits per second) using @Singleton annotated DAOs is faster and better
resource wise than using Default Scope?
As we use @Singleton for our DAOs we don't inject the EntityManager
directly but use an EntityManagerProvider which, as I understand it, is
the correct way as the Provider is considered threadsafe which is a requirement for @Singleton.
Is there a "Google approved" way to include Hibernate using DAOs in your web application?
At what Layer would you set @Transactional? We had it on our DAO layer which was wrong as it led to a lot of single transactions (we are used to JEE where, on default, a transaction gets used if present). Now we have it in our Service Layer (Services, are also @Singleton which I also don't like...) which bundle/inject/use lots of different DAOs. Would you consider this to be correct to get proper transaction handling when bundling multiple DAOs?