Up to date, JPA compliant GenericDAO Implementation - spring

I read this article:
http://www.ibm.com/developerworks/java/library/j-genericdao.html
several times and believe I understand what it is saying. However, it is 4 years old and I have a JPA compliant Java application to contend with. In addition, I see that there is a JPATemplate in Spring that has some good functionality, but the Spring documentation says it is already deprecated!
Can anybody point me to a solid, modern, JPA compliant, Spring based, working example of a GenericDAOImpl that proxies an Interface to provide generic finder execution?

Nowadays JPA 2 in itself has become a decent implementation of a DAO layer since its responsibility (or contract if you wish) is the same as for the traditional "crafted" DAO, that is an isolation of a business logic from a storage mechanism. An important implication out of this is that you may need an explicit DAO only when working with non-DBMS storages like spreadsheet files, web-services, etc.

I've created a generic DAO mixing different approaches that I shared on SO in this question. I use these 2 approaches: DDD: The Generic Repository and JPA implementation patterns: Data Access Objects.
Please feel free to comment/edit if you think it can be improved.

Related

Should repositories in Spring Boot applications be tested directly?

Not sure if this will be considered a "legitimate question" or "purely opinion based", but is there a "best practice" with regards to directly testing a repository in a Spring Boot application? Or, should any integration testing simply target the associated service?
The reasoning for the question is simply the fact that, for the most part, a repository in a Spring Boot application contains no project-generated code. At best, it contains project-defined method signatures which Spring generates implementations for (assuming correct naming conventions).
Thanks...
If you can mess it up, you should test it. Here the opportunities to mess up can include:
Custom Queries (using #Query) might be wrong (there can be all kinds of logic mistakes or typos writing a query with no compile-time checking)
Repository methods where the query is derived from the method name might not be what you intended.
Arguments passed in, the type on the parameter list might not match the type needed in the query (nothing enforces this at compile time).
In all these cases you're not testing Spring Data JPA, you're testing the functionality you are implementing using Spring Data JPA.
Cases of using provided methods out of the box, like findOne, findAll, save, etc., where your fingerprints are not on it, don't need testing.
It's easy to test this stuff, and better to find the bugs earlier than later.
Yes, I think is a good pratice to do that. You could use #DataJpaTest annotation, it starts a in memory database. The official documentation says:
You can use the #DataJpaTest annotation to test JPA applications. By default, it configures an in-memory embedded database, scans for #Entity classes, and configures Spring Data JPA repositories. Regular #Component beans are not loaded into the ApplicationContext.
Link to the docs: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html
Starting from the idea that repositories should be used only inside services and services are used to interact with the other layers of the system, I would say that testing services should be enough in the majority of cases.
I would not test standard repository methods like findAll, or findBy.., they were tested already and the purpose is not to test JPA, but rather the application.
The only repository methods that should have direct tests are the ones with custom queries. These queries may be located in a shared library and it is not efficient to write similar tests across different projects(in this case regression is a big concern)

Implement a custom Spring Data Repository for a non-supported database

I want to implement a Spring Data Repository for a database which is not currentlty supported (hyphothetical question - no need to ask about the database).
How is this possible and where can I have an example of that?
Short answer is "yes, definitely". One of the main Spring-data's intentions is to unify access to different data storage technologies under same API style. So you can implement spring-data adapter for any database as long as it is worth implementing a connector to that database in Java (which is definitely possible for the majority of databases).
Long answer would take several blog posts or even a small book :-) But let me just highlight couple of moments. Each of the existing spring-data modules expose one of (or both) the API flavors:
imperative - in a form of various template classes (e.g. RedisTemplate). It is mostly for the databases that don't have query language, but only a programmatic API. So you're just wrapping your db's API into template class and you're done.
declarative - in a form of so called Declarative Repositories, quite sophisticated mechanism of matching annotations on method signatures or method signatures themselves to a db's native queries. Luckily spring-data-commons module provides a lot of scaffolding and common infrastructure code for this, so you just need to fill the gaps for your specific data storage mechanism. You can look at slide deck from my conference talk, where I explained on a high level the mechanics of how particular spring-data module generates real implementations of repositories based on user declarations. Or you can just go into any of the existing modules and look into source code. The most interesting parts there are usually RepositoryFactory and QueryLookupStrategy implementations.
That is extremely simplified view of the spring-data concepts. In order to get more detailed information and explanations of core principles, I'd suggest reading spring-data-commons reference documentation and having a look at spring-data-keyvalue project, which is a good starting point to implement Spring Data Module for key-value storages.

Frameworks and specification for JPA, CDI and JSF

I have read and I have understood that JPA, JSF, CDI are only specifications. Such as:
JPA - [Hibernate, Toplink], JSR-000338
CDI - [Spring - Google Guice, PicoContainer], JSR299
JSF - [Primefaces, IceFaces, RichFaces], JSR-000314
So, if they are only specification in a paper, why the packages says, "javax.persistence...", “javax.faces."?
I think that Oracle says: Here is this paper where are the rules. If you want to implement it you must to use my package name ("javax.persistence...", " javax.faces."), and as pay, you can add more features and you will can to put your own package for the extended features?
Other thing, if I study the specifications (jpa, cdi, jsf), Will I be able to use whatever framework? Or even, to construct my software without them?
Please explain me that.
Best regards.
First of all, neither Spring, nor Guice (and not PicoContainer either, AFAIK) are CDI implementations. JBoss Weld is a CDI implementation.
Second. The specification is not just a paper. It's also a set of interfaces and classes that every implementation must correctly implement or extend or which even contain core functionalities that don't depend on the implementation (see Persistence, for example). Those interfaces and classes are the ones that are in the javax package. They're part of the specification itself, and implementations may not modify them.
The idea of a standard is indeed that by relying on the rules described in the specifications, you should be able to use whatever framework implementing the specifications. Beware, though, that some parts are sometimes left unspecified, and that implementations, even without bugs, can do some things differently.
Implementing your software without an implementation would, theoretically, be possible, as long as the user of your software chooses the implementation it wants. But that is extremely unrealistic: you will have to test your software and thus choose an implementation for your tests. And if you plan on supporting several implementations of the specification, you will have to test your software wilth all of them, and even probably need to make adjustments.

Usecase of Spring DAO

I'm wondering what is the typical usecase of Spring DAO where we can easily switch between different persistence frameworks.
Apart from abstracting the boiler-plate code (for JDBC, Hibernate like) Why does any application want to change its ORM frameworks so frequently?
By using a DAO pattern with a distinct DAO interface, this enables you to mock the DAO implementation. With this you improve testability of your code, as you are then able to write tests that do not need database access.
It is not only about frequently being able to switch between ORM frameworks, but is also about reducing effort if you are enforced to change the ORM.
Another reason is, that you might have different data sources like a database, a webservice or the file system for example. In this case you don't abstract the ORM but simply the persistence mechanism in general.
I think the real important idea behind DAOs are that you have just one spot where all data access related code for a particular entity ist located. That makes testing and refactoring of your persistence layer easier and your code is better readable.
Furthermore, it makes the code better readable. Think of a new developer in your team that should implement a feature. If she needs to access the databasase she would look into the dao for data access methods.
If you scatter the data access code in different services the risk is pretty high that someone produces code duplicates.

What is the problem with not using Spring

I am trying to understand Spring. I have read about it and done some tutorials. I kind of get the IoC paradigm and the fact that DI is its implementation in Spring.
My question is this: What do you lose by not using Spring? I understand this is a big question and somewhat subjective. But if you could write a few dot points or give an example of a problem that could occur if Spring was not used, I think that would help me and many other people.
Spring is far more than just another IoC tool (think of DAO related stuffs, convenient MVC support, testing tools, ...). In my opinion, it has gradually grown to a kind of "flavor" of Java. But that's not the point :)
Speaking of IoC/DI, what you loose not using it is the easiest way to gain loose coupling in your application, that is associated to reusability. Obviously, most of people tend to think of reusability of a component in another project, which, in my experience, occurs not that often. Greatest benefit of reusability appears when you have to unittest your code.
Programming through interface and using DI/IoC make unittests so easy that even those who are reluctant to unit test will start loving it.
Loose coupling and benefit in matter of UT is one thing you'll lose.
There are no problems actually. But if you start writing your code you will end up with a homegrown framework much like Spring. The thing you get with using Spring is that the framework is already more generic (than your own) and you can use it in a lot of different projects. And the most important (maybe) is that Spring is well tested with so many users using it.
Of course you can try also another framework not just Spring. There are a lots out there...
I did a write-up on why people use dependency injection frameworks (like Spring and Google Guice). Most tutorials neglect this, but IMHO it is the most important thing.
If you understand the problem you have, and what problems all these patterns/frameworks solve, only then are you able to make good software and great architectural choices.
Read about it here: http://www.redcode.nl/blog/2010/01/dependency-injection-dissection
Put simply, you apply dependency injection to write clean and testable code. Also in return you achieve a design in which the caller knows which implementation to use(inject) rather than callee (this is what's famous as the "Hollywood principle"). Now if you don't use use DI frameworks like Spring and Guice you try to achieve dependency injection using factories. But factories come with a cost of boilerplate code and uneasy clean-up while testing. Some people also find other strengths in these frameworks which is their easy integration with frameworks belonging to different tiers like Struts, Hibernate etcetera.
A glib answer is that you'd have to code it all yourself. I don't know much about Spring (yet), but even the basic act of constructor injection would require a lot of code whereas with Spring you need two edit points:
In config:
<sectionGroup name="spring">
<section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
</sectionGroup>
<spring>
<context>
<resource uri="config://spring/objects"/>
</context>
<objects xmlns="http://www.springframework.net">
<object name="mediaLibrary" type="AlbumLibraryWPF.AlbumLibrary, AlbumLibrary"/>
</objects>
</spring>
In code:
IApplicationContext ctx = ContextRegistry.GetContext();
library = (Library)ctx.GetObject("mediaLibrary");
Which would you rather do: write a DI framework yourself or concentrate of building your solution?
Spring is much more than a DI framework. There a lot of areas that it will make programming easier for you:
JDBC, Hibernate, JMS templates (dramatically reduce code line count)
Aspect programming
Security (Spring security)
Spring MVC
Spring Web Services
These are just some examples - there are many more. You don't have to use any of the above, but there all part of a mature, well designed framework and in general they make things easier.
The core of Spring is of course Dependency Injection. The benefits of using a DI framework may not be apparent for small projects, but there are more than evident for large and complicated ones. Martin Fowler explains Inversion of Control very clearly. Of course there other alternatives (Guice for example), but I would say that Spring is now an industry standard.
IoC is mostly a good thing within the Java language because when most applications start growing and you don't design for modularization/loose coupling, you end up with a big pile of interconnected classes without no sensible boundaries.
For starters, Spring and other IoC/DI frameworks makes you think about modularization right from the start. This is big because if you have your code well modularized/loose coupled, you end up componentizing and reusing much more wich leads to better unit testing (if you do unit testing anyway).
If I want to write a DAO, I can define its interface up front:
interface IPersonDao {
List<Person> getPersonsByTeam(String teamName);
}
then, I can just call for the implementation of this interface from anywhere in the src where's Spring is being "applied". Suppose i need it in a service layer:
class MyService {
#Autowired
IPersonDao svc;
}
or in a test class:
class TestPersonDao {
#Autowired
IPersonDao svc;
#Test
void testGetPersons(){
List<Person> persons = svc.getPersonsByTeam("billing");
Assert.assertDataSet(persons, "billing.xml");
}
}
Besides, my Dao implementation can hide the complexities of data access without messing with the Dao contract. If I require a hibernate session or a persistence manager, I just declare that:
class JpaPersonDao implements IPersonDao {
#PersistenceContext
EntityManager em;
List<Person> getPersonsByTeam(String tm) {
em.createQuery("...");
}
}
Componentization of classes requires a registry in order to wire collaborating beans. This could be developed by hand, but there are already DI frameworks that do this. Besides, Spring has alot of other stuff like exception translation, support for aspect programming, mvc frameworks, portlet frameworks, integration with hibernate, jpa and/or other db stacks which of course integrate nicely with the Spring IoC stuff.

Resources