I am looking into Spring data and one thing I've noticed is that we're able to perform CRUD operations just by creating an interface which implements the CRUD repository and by default, we're given access to generated queieres to the db via the method name.
I thought whenever we implement an Interface, we need to provide an implementation to the methods. So why don't we override anything when we use an interface which implements from the CrudRepository interface?
One of the goals of Spring Data is to make database access easy, without the need to manually write a lot of boilerplate code.
Traditionally, one of the things developers commonly did when working with a database is write DAOs (database access objects) with methods, where each method would do a specific query. Such methods would typically be boilerplate code - simple, repetitive code that's a lot of work to write and maintain and that doesn't contain any business logic.
When you use Spring Data, all this code is automatically generated for you. The only thing you have to do is specify in a repository interface what query you want to do, and Spring Data then interprets the meaning of the method name to automatically generate the code that does the query for you.
That saves you a lot of time and helps you a great deal to keep your own code concise; it also helps with the prevention of bugs.
The implementation of a Spring Data repository interface is generated automatically at runtime. This isn't done by generating source code which is compiled - behind the scenes Spring Data directly generates the bytecode of the implementation of the interface.
Related
I have been working with Spring Data JPA repository in my project for some time and I know the below points:
In the repository interfaces, we can add the methods like findByCustomerNameAndPhone() (assuming customerName and phone are fields in the domain object).
Then, Spring provides the implementation by implementing the above repository interface methods at runtime (during the application run).
I am interested on how this has been coded and I have looked at the Spring JPA source code & APIs, but I could not find answers to the questions below:
How is the repository implementation class generated at runtime & methods being implemented and injected?
Does Spring Data JPA use CGlib or any bytecode manipulation libraries to implement the methods and inject dynamically?
Could you please help with the above queries and also provide any supported documentation ?
First of all, there's no code generation going on, which means: no CGLib, no byte-code generation at all. The fundamental approach is that a JDK proxy instance is created programmatically using Spring's ProxyFactory API to back the interface and a MethodInterceptor intercepts all calls to the instance and routes the method into the appropriate places:
If the repository has been initialized with a custom implementation part (see that part of the reference documentation for details), and the method invoked is implemented in that class, the call is routed there.
If the method is a query method (see DefaultRepositoryInformation for how that is determined), the store specific query execution mechanism kicks in and executes the query determined to be executed for that method at startup. For that a resolution mechanism is in place that tries to identify explicitly declared queries in various places (using #Query on the method, JPA named queries) eventually falling back to query derivation from the method name. For the query mechanism detection, see JpaQueryLookupStrategy. The parsing logic for the query derivation can be found in PartTree. The store specific translation into an actual query can be seen e.g. in JpaQueryCreator.
If none of the above apply the method executed has to be one implemented by a store-specific repository base class (SimpleJpaRepository in case of JPA) and the call is routed into an instance of that.
The method interceptor implementing that routing logic is QueryExecutorMethodInterceptor, the high level routing logic can be found here.
The creation of those proxies is encapsulated into a standard Java based Factory pattern implementation. The high-level proxy creation can be found in RepositoryFactorySupport. The store-specific implementations then add the necessary infrastructure components so that for JPA you can go ahead and just write code like this:
EntityManager em = … // obtain an EntityManager
JpaRepositoryFactory factory = new JpaRepositoryFactory(em);
UserRepository repository = factory.getRepository(UserRepository.class);
The reason I mention that explicitly is that it should become clear that, in its core, nothing of that code requires a Spring container to run in the first place. It needs Spring as a library on the classpath (because we prefer to not reinvent the wheel), but is container agnostic in general.
To ease the integration with DI containers we've of course then built integration with Spring Java configuration, an XML namespace, but also a CDI extension, so that Spring Data can be used in plain CDI scenarios.
My application has about 50 entities that are displayed in grid format in the UI. All 50 entities have CRUD operations. Most of the operations have the standard flow
ie. for get, read entities from repository, convert to DTO and return a list of DTO's.
for create/update/delete - get DTO's - convert to entities, use repository to create/update/delete on DB, return updated DTOs
Mind you that for SOME entities, there are also some entity specific operations that have to be done.
Currently, we have a get/create/update/delete method for all our entities like
getProducts
createProducts
updateProducts
getCustomers
createCustomers
updateCustomers
in each of these methods, we use the Product/Customer repository to perform the CRUD operation AFTER conversion from entity -> dto and vice versa.
I feel there is a lot of code repetition and there must be a way by which we can remove so many of these methods.
Can i use some pattern (COMMAND PATTERN) to get away with code repetition?
Have a look at the Spring Data JPA or here project. It does away with boilerplate code for DAO.
I believe it basically uses AOP to interpret calls like
findByNameandpassword (String name,String passwd)
to do a query based upon the parameters passed in selecting the fields in the method name (only an interface).
Being a spring project it has very minimal requirements for spring libraries.
Basically, you have 2 ways to do this.
First way: Code generation
Write a class that can generate the code given a database schema.
Note that this you will create basic classes for each entity.
If you have custom code (code specific to certain entities) you can put that in subclasses so that it doesn't get overwritten when you regenerate the basic classes.
Object instatiation should be via Factory methods so that the correct subclass is used.
Make sure you add comments in the generated code that clearly states that the code is generated automatically (so that people don't start editing them directly).
Second way: Reflection
This solution, while being more elegant, is also more complex.
Instead of generating one basic class for each entity you have one basic class that can handle any entity. The class would be using reflection to access the DTO:s.
If you have custom code (code specific to certain entities) you can put that in other classes. These other classes would be injected into the generic class.
Using reflection would require a strict naming policy on your DTO:s.
Conclusion
I have been in a project using the first method in a migration project to generate DTO classes for the service interface between the new application server (running java) and the fat clients and it worked quite well. We had more than 100 generated DTO classes. I am aware that what you are attempting is slighty different. Editing database records is a generic problem (all projects need it) but there aren't (m)any frameworks for it.
I have been thinking about creating a generic tool or framework for it but I have never gotten around to it.
I have a project implemented in a (flawed) 3-tier architecture. My job is making it more generic so that it would be easy to add a new database into the project.
Concrete: there is a databaseFacade for an SQL database and i have to make it more generic so we can add multiple databases very easy. In this case writing it to a CSV file.
My idea in the database layer was to make a interface where all the methods are defined. Then having the database facade (depending which you want to use) implementing this interface so that it becomes more generic.
Then i have some kind of DBmanager class. This DBmanager class will read out a config file so he knows what database to use. Based on this info he will create an instance of the interface and return this to the application layer.
However this is where I don't know if i'm correct. The application layer now has a DBmanager class (where everything is correctly encapsulated only 1 method is public for returning the facade) and after that the DBfacade.
Any thoughts about the correctness of this? Since I'm having doubts.
I've seen a PHP system (Moodle) use almost exactly this pattern and it works fine. All that happens is that the DB type is specified as a config variable and the concrete DB access class is instantiated as the global DB manager object, providing the facade methods e.g. get_records(), which returns a standardised array of row objects. Arguable whether you would call this facade or adapter, but that's hardly a worry.
I'd say go for it with your current plan. You seem to have decoupled the layers properly and understood the purpose of the patterns. Also, the way your low level (DB) and high level (application controller) components both depend on a single DB facade interface in the middle is a good example of dependency inversion, so bonus points for that! :)
This is the correct approach. One minor quibble is that your DBManager actually follows the Factory pattern, and so should be called DatabaseFacadeFactory, assuming that your facade class is called DatabaseFacade.
As you become more comfortable with Java, check out Spring. It provides a lot of tools and techniques that automatically handle situations such as this, and remove the need for much of the boilerplate code. For more information, see dependency-injection.
To me, it seems legit. I'm not an expert in software architecture yet, but your description describes similar concept in comparison to how JDBC was designed.
I am confused about the structure of creating service layer and DAO layer:
in some examples I see some people creating interface+implementation for both service and DAO and in other examples I see people creating implementation only specially when the DAOs extends an AbstractDao class that contains generic methods for those DAOs, so I am confused about what to go for, why to go for this solution or the other one, and what is the best practise (commonly used) please advise.
I suggest to create interfaces for service and for DAO. Very often you would like to mock service in unit tests of code, that use this serice.
Also Spring, for example, forces you to use interfaces when you are using some Spring proxies for example for transactions. So you should have an interface for service.
DAO is more internal part, but I always try to use interfaces for them to simplify testing.
I prefer interface + implementations for the following reasons:
Interfaces becomes contracts: they tell you what is available to call, and you never worry about the implementation thereof, provided that the result is expected.
You can create customizable implementation of the interface without breaking other implementations of the same interface (generally useful when writing unit test). Customizing an implemented only class can bring more error than you don't notice easily.
It creates a framework that can be documented.
Implemented subclasses are used to create the business/application logic that conforms to the interface contract.
I have only done the implementations of service layer, didn't bother with interfaces (except where I had to). I probably should get around to writing the interfaces, but no problems so far. I am doing unit testing just fine without mocking the service layer.
Also, I don't have a DAO layer, as I am using hibernate and it seemed overkill. A lot of my reasoning is based on this blog, eloquently written by Bozho.
I think it is quite debatable (whether to have DAO and hibernate), however I am quite happy with my decision, I pass in thick domain objects and then just make a call to the hibernate session. Each method on the dao layer would literally only be one line (session.persist(mObject), or similar).
One argument I heard against it was a dao layer would make it easier to change/remove orm at a later date. I am not sure if the time spent coding the dao layer in the first place added to the time coding the change, would be less than coding the change without dao layer on its own. I have never had to change ORM technology any where I worked so its a small risk.
From my point of view when you say Service you should have interfaces and if you can't provide or will not provide that, then you don't have the contract between the service and the consumer and it's not a service anymore, you can call it anything else
The interface+implementation is used in order to have loose coupling. You have the flexibility of changing or switching implementations easily without major changes in code.
Think of a scenario where you are using Hibernate for persistence(DAO Layer) and you need to switch to JPA or iBatis or any other ORM for that matter.
If you are using interfaces, you can simply write an implementation specific to JPA and "plug" it in place of Hibernate. The service code remains the same.
Another argument for interface+implementation model is that proxies for interfaces are supported by Java itself while creating proxies for implementations requires using library such as cglib. And this proxies are necessary for transaction support etc.
Check out my post about "fastcode" an eclipse-spring plugin that generates the service layer off your DAO's. Works like a charm.
generate service /dao layer for GWT/Spring/Hibernate/PostgreSQL
I'm hesitating between two designs of a database project using Hibernate.
Design #1.
(1) Create a general data provider interface, including a set of DAO interfaces and general data container classes. It hides the underneath implementation. A data provider implementation could access data in database, or an XML file, or a service, or something else. The user of a data provider does not to know about it.
(2) Create a database library with Hibernate. This library implements the data provider interface in (1).
The bad thing about Design #1 is that in order to hide the implementation details, I need to create two sets of data container classes. One in the general data provider interface - let's call them DPI-Objects, the other set is used in the database library, exclusively for entity/attribute mapping in Hibernate - let's call them H-Objects. In the DAO implementation, I need to read data from database to create H-Objects (via Hibernate) and then convert H-Objects into DPI-Objects.
Design #2.
Do not create a general data provider interface. Expose H-Objects directly to components that use the database lib. So the user of the database library needs to be aware of Hibernate.
I like design #1 more, but I don't want to create two sets of data container classes. Is that the right way to hide H-Objects and other Hibernate implementation details from the user who uses the database-based data provider?
Are there any drawbacks of Design #2? I will not implement other data provider in the new future, so should I just forget about the data provider interface and use Design #2?
What do you think about this? Thanks for your time!
Hibernate Domain objects are simple POJO so you won't have to create separate DPI-objects, H-Object themselves can be used directly. In DAO you can control whether they come from hibernate or anything else.
I highly recommend reading Chapter 4 "Hitting the database" of Spring in Action, 3rd edition, even if you aren't using Spring in your application. Although my second recommendation would be to use Spring :-)
The DAO pattern is a great way to keep database and ORM logic isolated in the DAO implementation, and you only need one set of entity objects. You can make that happen without Spring, it just takes more work managing your sessions and transactions.
If I understand your post, this is sort of a middle-ground between Design 1 and Design 2. The H-Objects (the entities that Hibernates loads and persists) don't need any Hibernate specific code in them at all. That makes them perfectly acceptable to be used as your DPI-Objects.
I've had arguments with folks in the past who complain that the use of JPA or Hibernate Annotations exposes Hibernate specifics through the DAO interface. I personally take a more pragmatic view, since annotations are just metadata, and don't directly affect the operation of your entity classes.
If you do feel that the annotations expose too much, then you can go old school and use Hibernate Mappings instead. Then your H-Objects are 100% Hibernate free :-)
I recommend design #2. Simply construct domain objects, and let hibernate look after them. Don't write separate classes that are persisted.
Hibernate tries to hide most of the persistence business from you. You may need to add a few small annotations to your entities to help it along. But certainly don't make separate classes.
You may need some very small DAO classes. For example, if you have a Person entity, it would be fairly common practice to have a PersonDAO object that saves a person. Having said that, the code inside the DAO will be very simple, so for a really small project, it may not be worth it. For a large project, it's probably worth keeping your persistence code separate from your business logic, in case you want to use a different persistence technology later.