Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring @Repository best practices

Context: Web application

I haven't used Spring before, but according to the Spring docs, all the beans are singleton, unless we declare them as prototype.

  • Without using Spring:

Normally I instantiate new DAO when there is a call to the business/service layer. If it is a RESTfull service, I instantiate almost all the objects which depend on the call.

  • With Spring:

I can annotate data access classes with @Repository and also I can use @Service for service layer classes.

So my classes with above annotations are singleton by default. There is a @Scope annotation that we can declare them as prototype, but nobody seems doing this.

  • Without Spring : new Object(); each time
  • With Spring: singleton

My questions are,

  1. The way I used before (creating new instance each time) is incorrect ?
  2. If @Repository is singleton, how does it handle thread safety when there is no such a thing addressed? (Assume it is done by spring proxies)
  3. What is the best practice, @Repository is enough or adding @Scope('prototype') would be better ?
  4. I don't see anyone use @Scope('prototype') with @Repository (according to the tutorials, blogs, etc). Is there a well know reason?
  5. What if my DAO class is accessed by multiple large number of threads with very high frequency? (This is the one I concern the most)

Thanks

like image 318
sura2k Avatar asked Jan 20 '15 07:01

sura2k


People also ask

What is @repository used for in spring?

Spring @Repository annotation is used to indicate that the class provides the mechanism for storage, retrieval, search, update and delete operation on objects.

Is @repository mandatory in spring boot?

It is indeed not necessary to put the @Repository annotation on interfaces that extend JpaRepository ; Spring recognizes the repositories by the fact that they extend one of the predefined Repository interfaces. From the javadoc: Annotation to enable JPA repositories.

Do you need @repository annotation?

We don't need to use @Repository annotation when we are extending JpaRepository because Spring detects that the predefined JpaRepository has been extended and recognises the interface that extends JpaRepository as a repository.

What is @repository in spring boot?

@Repository Annotation is a specialization of @Component annotation which is used to indicate that the class provides the mechanism for storage, retrieval, update, delete and search operation on objects.


2 Answers

You're correct - in Spring world most of the beans are singletons.

  1. The way I used before (creating new instance each time) is incorrect ?

It is not incorrect since it works. The problem about it is that you instantiate a new instance of DAO on each request - in some cases it might be expensive, and anyway it doesn't make any sense - why would you need a bunch of DAO instances? Spring on the other hand not only creates a singleton but also injects DAO's to services or other DAO's e.t.c. i.e. does a lot of work for you

  1. If @Repository is singleton, how does it handle thread safety when there is no such a thing addressed? (Assume it is done by spring proxies)

When you are writing a @Repository bean, you would normally inject there a DataSource or an EntityManager. DataSource.getConnection() method should be thread safe. With regard to EntityManager, Spring will inject a proxy which will behave differently for different threads, i.e. different threads won't share the same JPA session.

  1. What is the best practice, @Repository is enough or adding @Scope('prototype') would be better ?

The best practice (or rather a most wide-spread approach) is to just use @Repository

  1. I don't see anyone use @Scope('prototype') with @Repository (according to the tutorials, blogs, etc). Is there a well know reason?

The reason is that there's no profit from creating multiple instances of @Repository beans

  1. What if my DAO class is accessed by multiple large number of threads with very high frequency? (This is the one I concern the most)

Again here singleton is better than creating a new object for each request. Just avoid redundant synchronization so your threads won't block on some monitor

like image 185
bedrin Avatar answered Sep 23 '22 05:09

bedrin


  1. No, but it's much harder to unit test, which is what dependency injection is all about. By injecting a DAO in a service, you can easily unit-test the service by injecting a mock DAO during the test. That's not possible if the service creates its own DAO.

  2. A repository is typically completely stateless except for a thread-safe entity manager, session factory or JDBC template initialized at startup time, so being called concurrently is not a problem: it's thread-safe.

  3. There's no reason for a repository to be a prototype. Injecting a prototype DAO into a singleton service will still cause each prototype to be called concurrently anyway.

  4. There's no reason to do it.

  5. No problem: it should be thread-safe if coded correctly.

like image 27
JB Nizet Avatar answered Sep 19 '22 05:09

JB Nizet