I start working with Spring and have some confusions about its conventions.
Is it fine to put Repositories in Controller?
In a Service class, If I want to reuse code could I inject other Services and other Reposities?
is it the best practice to name Service And Repository class is based on Entity name i.e: User -> UserRepository->UserService?
No, don't use Repositories in the Controller. Only in the Services.
And don't use Entities in your Controller. Create Dto (Data Transfer
Objects) Object from the Entities and work with this in your
frontend
Yes you can use other services and respositories in your service class
Yes it is. Name the interfache UserService and the implementation UserServiceImpl
Check also answer:
It explains the Persistence Bussines and Presentation layers
https://stackoverflow.com/a/34084807/2218992
Related
My application is based on Spring Boot, Hibernate, MySQL using Spring Data JPA to stitch them.
Use case is to use slave db node for doing heavy read operations so as to avoid all traffic being served from master mysql node. One way of achieving this is to have multiple Entity Managers pointing to separate data sources(one to master and other to slave node). This way has been explained quite well in below SO questions and blogs.
Spring Boot, Spring Data JPA with multiple DataSources
https://scattercode.co.uk/2016/01/05/multiple-databases-with-spring-boot-and-spring-data-jpa/
Where I am stuck is to understand if there is a way I can inject different entity managers for different use cases in my Repository Annotated Interface.
The only way I see it can be done is extending repository with a custom implementation which gives uses custom entity manager annotated with relevant persistenceContext like below.
public interface CustomerRepository extends JpaRepository<Customer, Integer>, MyCustomCustomerRepository{
}
public class MyCustomCustomerRepositoryImpl implements MyCustomCustomerRepository {
#PersistenceContext(unitName = "entityManagerFactoryTwo")
EntityManager entityManager;
}
I would like to avoid doing this custom implementation. Any help around solving this use case(which I feel should be very common) would be appreciated.
NOTE: Entities are same in both databases so giving separate packages for entity scanning and similar solutions might not work.
Here is a nice sample you can use:
dynamic-datasource-routing-with-spring.
Inside you can find an AbstractRoutingDatasource + an interceptor for a custom annotation that wires the service method to a required database.
However you can just use datasource switch explicitly.
Below is the pull request that shows the diff and how I made it work with most configurations annotation driven instead of xml. It is based on cra6's answer above. i.e. using spring's RoutingDataSource capability.
https://github.com/himanshuvirmani/rest-webservice-sample/pull/1/files
I am using spring data JPA repository, my requirement is when i call repository class methods in service class it should show only custom methods like addUser(X,Y) instead of save().
Few things i understand, implementation of spring repository is provided by spring framework at runtime, So we cannot provide out own implementation. (This will overhead).
All methods in JPARepository is public only, so its obivious when we implement this interface all methods will be visible through out.
I am thinking of using DAO and Repository both at same time. DAO will provide custom function signature and repository will implement DAO interface.
Any Hack ?
If you don't want the methods from JpaRepository or CrudRepository, don't extend those but just Repository instead. It is perfectly fine to have a repository interface like
MyVeryLimitedRepository extends Repository<User, Long> {
User findByName(String name);
}
Of course methods like addUser(X,Y) will need a custom implementation.
You can very well use DAO pattern in this case .
By implementing DAO Pattern in Service Class
You create a wrapper between Service and Repository.
You can custom code your DAO layer to only expose custom methods to service layer
Last year when I started learning spring I remember an article that expalined that not all pojos are to be defined as beans. So I'm planning to create a web app say EmployeeMaintenance. CRUD Functionalities are there. I will surely end up creating pojos like Employee , EmployeeSupplementaryDetails, Address etc. Should I makes these beans and configure them in xml or annotate whatever. I'm sure my understanding of bean is not enough. I know that Dbconn , services etc should definitely be declared as bean.
All I need is what are the parameters I should consider before I make a pojo a Spring Bean.
General rule for making Java class a Spring bean is to ask yourself if you need to inject object into some other object or if you want the object to be managed by Spring components. The classes you listed as example doesn't seem to be good candidates for being Spring beans - they represent model data and will be passed as some service's methods parameters.
Examples of typical CRUD application beans:
EmployeeService (you would want to inject it to controller or other service)
EmployeeRepository / EmployeeDao
EmployeeController (it will be bean managed by Spring's MVC framework)
etc.
Spring beans are building blocks of your application. Let's suppose you need to create web application for storing and managing employees records (creating, retrieving, updating, deleting). What you will need is web controller that will handle incoming requests for several operations (EmployeeController). Good practice is that controller doesn't implement any business logic - all it should do is to delegate work to service beans. So you would need bean like EmployeeService. Then controller would ask service to do some work (give me employees list / remove John Smith from database / change salary for Ann Jackson / etc). So service will be controller's dependency (service is injected into controller). Service can also have some dependencies (like repository object, which is responsible for handling communication with data storage) and these dependencies would be injected to service. Dependency management is Spring's core feature.
Good practice in object oriented programming is to have small classes that are responsible for doing one kind of actions. Such objects are much easier to test and understand. The more classes you have, the building application from blocks is harder, so it's worth to delegate it to framework like Spring. Without Spring you would need to create controller class, then inside of it create service, then inside of it create other dependencies and so on. Spring does it for you, so all you need to do is to declare dependencies and they will be injected automatically. If you want to replace implementation of your service with another (for example repository that used XML file for storing data with repository storing data in relational database) then you just have to change your bean definition.
Regarding to beans managed by Spring, typical example is database transaction manager (eg. org.springframework.orm.jpa.JpaTransactionManager). If you define such bean, and declare which methods should be transactional, then Spring will take care of transactions management (will open, commit or rollback transactions automatically).
I have been looking at various examples of how to use Spring with REST. Our end target is a Spring HATEOAS/HAL setup
I have seen two distinct methods for rendering REST within Spring
Via #RestController within a Controller
Via #RepositoryRestResource within a Repository
The thing I am struggling to find is why would you use one over the other. When trying to implement HAL which is best?
Our database backend is Neo4j.
Ok, so the short story is that you want to use the #RepositoryRestResource since this creates a HATEOAS service with Spring JPA.
As you can see here adding this annotation and linking it to your Pojo you have a fully functional HATEOAS service without having to implement the repository method or the REST service methods
If you add the #RestController then you have to implement each method that you want to expose on your own and also it does not export this to a HATEOAS format.
There is a third (and fourth) option that you have not outlined, which is to use either #BasePathAwareController or #RepositoryRestController, depending on whether you are performing entity-specific actions or not.
#RepositoryRestResource is used to set options on the public Repository interface - it will automatically create endpoints as appropriate based on the type of Repository that is being extended (i.e. CrudRepository/PagingAndSortingRepository/etc).
#BasePathAwareController and #RepositoryRestController are used when you want to manually create endpoints, but want to use the Spring Data REST configurations that you have set up.
If you use #RestController, you will create a parallel set of endpoints with different configuration options - i.e. a different message converter, different error handlers, etc - but they will happily coexist (and probably cause confusion).
Specific documentation can be found here.
Well, above answers are correct in their context still I am giving you practical example.
In many scenarios as a part of API we need to provide endpoints for searching an entity based on certain criteria. Now using JPA you don't have to even write queries, just make an interface and methods with specific nomenclature of Spring-JPA. To expose such APIs you will make Service layer which would simply call these repository methods and finally Controllers which will expose endpoints by calling Service layer.
What Spring did here, allow you to expose these endpoints from such interfaces (repositories) which are generally GET calls to search entity and in background generates necessary files to create final endpoints. So if you are using #RepositoryRestResource then there is no need to make Service/Controller layer.
On the other hand #RestController is a controller that specifically deals with json data and rest work as a controller. In short #Controller + #ResponseBody = #RestController.
Hope this helps.
See my working example and blog for the same:
http://sv-technical.blogspot.com/2015/11/spring-boot-and-repositoryrestresource.html
https://github.com/svermaji/Spring-boot-with-hibernate-no-controller
#RepositoryRestController override default generated Spring Data REST controllers from exposed repository.
To take advantage of Spring Data REST’s settings, message converters, exception handling, and more, use the #RepositoryRestController annotation instead of a standard Spring MVC #Controller or #RestController
E.g this controllers use spring.data.rest.basePath Spring Boot setting as base path for routing.
See Overriding Spring Data REST Response Handlers.
Be aware of adding #ResponseBody as it is missed in #RepositoryRestController
If you not exposed repository (marked as #RepositoryRestResource(exported = false)), use #BasePathAwareController annotation instead
Also be aware of bags
ControllerLinkBuilder does not take Spring Data REST's base path into account and #RequestMapping shouldn't be used on class/type level
and
Base path doesn't show up in HAL
Workaround to fix link: https://stackoverflow.com/a/51736503/548473
UPDATE: at last I prefer not to use #RepositoryRestController due to lot of workarounds.
All the examples I've seen so far integrating spring/mvc with JSF uses DAO class, DAOImp, Service, ServiceImp and then JSF ManagedBean and as far as I know with EJB 3.1 all I need is EJB and JSF ManagedBean. I am not mentioning entities. So based on my understanding with Spring + JSF I need:
5 classes and with EJB + JSF I need only two classes. Please correct me if am wrong but if am right then what's the advantage of using spring with JSF.
Thanks.
You are wrong. -- You can skipp the DAO, DAOImpl and ServiceImpl if you want to implment all in the Service Class.
But even in EJB it is best practice to seperate the Service and the DAOs.
The usage of Interfaces is a kind of style. If you use interfaces, at least you can skip them to and create your services (and Dao) like EJB 3.1 interface free Beans (I don't know the correct name at the moment). At least there are the same pro and cons to use interfaces in Spring and EJB 3.1.
Summary: You can build Spring JSF2 Apps with 2 classes to, but it is best practice to seperate at least JSP (view), Service (EJB's) and DAOs.
comment by Spring or JSF: Ralph please give me an example, suppose I've an entity: Person with id, firstName and lastName what would be the code I need from spring aspect?
In traditonal Spring architecure you have the:
Person (Entity) Class -- the one with the #Entity
PersonDao - Interface that provides data base Load, Strore, Delete and Find Methods for the Person
PersonDaoImpl - implementation of the PersonDao Interface - (#Repository)
PersonService - Interface that provides business functionality arround the person, for example a create method that send an email after a person is created
PersonServiceImpl - Implementation of the PersonService Interface - it uses for example the PersonDao and other Sevices to provides its functionality (#Service)
PersonJSF-Managed Bean - handles the JSF stuff but has no business functionality, it uses the PersonService (or an other Service) to start business functionality
This is one of the most common architecural style (not only in Spring). But even for this there are some variants:
how DAO's can be invoked? All Dao Functions must be invoked via the according Service -- or direct
DAOs with or whithout Interfaces? (may you need the Interfaces for your Test Mock Framework?) -- (have a look at Hades, there is only the Interface, but in most cases no Impl)
Services with or whithout Interfaces? (
...
BTW: one other very intresting architural style, is the one hat Spring ROO uses: It has only the View (PersonController) and the Model (Person), and all DAO and Service Functionality is put in the Model class. -- That is a bit of real OO Design.