When I was asked to write a book about Spring Data by Packt Publishing, I was stunned. To be honest, I could not believe that this was happening to me. I know that this is a huge cliche but it felt like a dream. I almost had to pinch myself to ensure that I was awake. And today, after months of hard work, I am proud to announce that my Spring Data book is published.
All Theory And No Play
I have read my share of programming books and noticed that many of them have two common problems:
- The book is all about theory. These books are great if you want to impress your buddies and seem smarter than you really are. However, if you want to actually learn something, it can be hard to apply the theory to practice.
- The sample code of the book is considered only as a byproduct. In other words, the sample projects might be messy and it can be hard to run them. I learn by doing and books like this won’t allow me to make small modifications to the sample code and see what happens. I hate this.
I wanted to do something different. Spring Data is a practical hands-on guide and it includes only the theory that is absolutely necessary. As an additional bonus, you receive fully functional example applications that demonstrate the topics covered in this book.
The Power of Two
As Chinese say, good things come in pairs. This book is no exception and it has two parts:
The first part is an "improved edition" of my Spring Data JPA tutorial. It teaches you to manage your entities and create database queries in an easy and productive way. The best part is that you can do this with less code than ever before. If you liked my Spring Data JPA tutorial, I promise that you will love the first part of my book.
The second part describes how you can use Redis key-value store in your Spring powered applications. You learn to use Redis as a data storage of your application, send and receive messages by using the Redis Publish/Subscribe implementation and use the Spring 3.1 cache abstraction with Redis. If you want to use Redis in your applications, the second part of my book will help you to get started in no time.
Don't Take My Word for It!
Still not sure if this a book for you? You are in luck because you don't have to take my word for it. These people have read the book and published their reviews:
- "Overall, Spring Data from Packt Publishing is a solid book that I recommend to everyone to read." - Mark Serrano
- "I will give this book 4 stars out of 5. The book is Brief but take the reader to learn how to use Spring Data using a well crafted and compact application." - Luis Peña
- "The book cover well both topics, the code is well written, but have some oddities" - Mario Arias
Buy Spring Data
I have one more request for you:
If you think that my book is useful to you, could you do me a favour and help me to spread the word? It would mean the world to me.
P.S. If you have any questions or comments concerning this book, feel free to leave a comment. I promise that I will answer to every comment.
Congratulations Petri! You did a great job!
Thanks for the compliment. Writing a book was actually a lot harder than I imagined but I think that I was able to create something useful.
Hi,
I'm still trying to extract some juice out of your book :-) I'm still unable to code my generic base repository common to all domain classes repositories. I have seen your latest articles in response to a previous comment and thank you for being so responsive and sharing with us. I hope you will not feel forced to to it again following this comment :-)
In your book at the page 79 you present the PaginatingContactRepository interface.
Then you show that the repository mechanism looks for an implementation class with the same name suffixed by Impl.
It would be nice if you explained why this mechanism, what it brings compared to using the implements keyword instead. You explain the how, but not much on the why.
On the next page, you follow up by saying that the name of our implementation class must be ContactRepositoryImpl. So I assume that the name of the interface is ContactRepository.
And this interface enters the stage only after, which makes the whole thing a bit harder to picture for a newbie. The reader could really benefit from you explaining more on the reason for this architecture.
Also, you make use of an entity manager in the implementation clas. The first thing I tried to do instead, was to use my domain class repository so as to make use of its JPA provided save method.
But there seems to be an issue with a circular dependency when attempting to do so: http://stackoverflow.com/questions/15124937/crudrepository-inside-my-custom-repository-implementation
Of course, you cannot explain all the intricacies of the JPA mechanism in one book :-)
As as coder, my aim is still to end up being able to lay out a generic base repository extended or implemented by all the domain classes repositories. I'm not there yet and wonder if I'll ever be.
Anyway, thanks for your articles and your good book !
Kind Regards,
Hi Stephane,
I have read your question and I will answer to it ASAP. However, I will have to take a look at my book and the sample project since I cannot remember exactly what I wrote about this.
Don't worry. I am 100% sure that you will be able to reach your goal.
Hi again Petri,
I now saw how to inject my domain class repository using the @Autowired annotation.
It was hidden in plain sight :-)
Sorry for the therefore invalid remark of mine !
Kind Regards,
Hi Stephane,
You mentioned that you wanted to create a base repository implementation which is shared by all repositories. However, page 79 of my book talks about adding custom methods to a single repository. You cannot use this approach for adding custom methods to all repositories.
If you want to learn how you can add a custom methods to all repositories, you should a section called Adding custom functionality to all repositories which starts at page 84. You might also want to read this blog post by Boris Lam: Customizing Spring Data JPA Repository.
However, I will also answer to the questions which you made in your original comment.
When you are adding custom methods to a single repository, the name of the class which implements the custom interface must be created by following this formula: [The name of the actual repository interface][Repository implementation postfix].
If you use the default value of the repository implementation postfix and the name of the actual repository interface is
ContactRepository
the name of the class which implements the custom interface must beContactRepositoryImpl
. This is a design decision made by the Spring Data team and to be honest, I don't know what is the main reason behind it.You made a good point when you mentioned that my book mostly explains how and leaves the why out of the picture. I will try to explain the benefits of adding custom methods to repositories in the following.
The biggest benefit of Spring Data JPA is that you can implement most of your queries with less code than using the "traditional" approach. However, there are situations when you might want to add custom methods to your repositories. These situations include:
The custom methods make it possible for you to use the "good stuff" of Spring Data JPA and gives you an opportunity to extend your repositories if needed.
Also, I agree that example might not work as good as I intended when you read it from a book. Have you downloaded the example source code from the website of Packt Publishing (Click the Support tab)? I think that seeing the whole source code would be extremely beneficial to you.
Hi Petri,
I have an issue when trying to use a sort clause on a findAll finder.
But it seems it is not an allowed construct.
Is it why your book does not showcase such a finder ?
I posted a thread at http://forum.springsource.org/showthread.php?138587-Method-name-query-derivation-on-findAll-with-a-sort-clause&p=447933#post447933
Kind Regards,
Hi Stephane,
The problem is that Spring Data JPA cannot parse the executed query from the method name of your query method.
Also, you do not need to implement a method which returns all
Admin
objects stored to the database. You can use one of the following methods:Admin
objects, you should use thefindAll(Sort sort)
method of theJpaRepository
interface.Admin
objects, you should use thefindAll(Pageable page)
method of thePagingAndSortingRepository
interface.About my book. I did not even try to implement a
findAll()
method by using query methods because the repository interfaces already offer several methods from which to choose.I hope that this answered to your question.
Hello Petri,
I was looking in your book for some information on how to do an update @Query as I have trouble doing my first one but I could not find any example of it. It would be nice to have and would fit well in your book.
Indeed, the user might need some guidance as I have seen posts on Stackoverflow from people running in trouble trying to do this basic thing. Myself as well :-) I'm running in a trouble http://stackoverflow.com/questions/17121620/spring-data-jpa-update-query-not-updating and also posted my bit.
I didn't think I should post an errata as it is nothing wrong with your book.
Kind Regards,
Hi Stephane,
It is nice to hear from you again, especially since you have an another interesting use case which was not covered in my book. I am planning to update my Spring Data JPA tutorial during the summer and I will add this scenario to it.
However, since this is not useful to you right now, I will take a closer look at this. I was able to reproduce this issue with the example application of my blog post which talks about the integration testing of Spring Data JPA repositories.
Unfortunately I cannot provide you an answer right now but I will let you know after I have found a solution to this problem.
Update: I was able to solve the problem by annotating the test method with the
@Transactional
annotation. I wrote a more detailed answer to your Stack Overflow question.Hi
I want to find a list of document object from multiple collections using Spring Boot Reactive Mongo Template. Do I need to do it in my repository or in Service. I'm using Mono and Flux methods.
Let Say
I've a collection of Person and another collection of User
How to find a name by id within two collections in a feasible(Because my collections has a large data) way.