Spring Data JPA Tutorial: CRUD

We have now configured the persistence layer of our Spring application. We are finally ready to create our first Spring Data JPA repository.

This blog post describes how we can create a repository that provides CRUD operations for todo entries.

Let’s get started.

Additional Reading:

If you are not familiar with Spring Data JPA, you should read the following blog posts before you continue reading this blog post:

Creating the Repository

Before we can create our first Spring Data JPA repository, we have to create an entity class that contains the information of a single todo entry. The relevant part of the Todo class looks as follows:

import org.hibernate.annotations.Type;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.PrePersist;
import javax.persistence.Table;
import javax.persistence.Version;
import java.time.ZonedDateTime;

@Entity
@Table(name = "todos")
final class Todo {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name = "creation_time", nullable = false)
    @Type(type = "org.jadira.usertype.dateandtime.threeten.PersistentZonedDateTime")
    private ZonedDateTime creationTime;

    @Column(name = "description", length = 500)
    private String description;

    @Column(name = "modification_time")
    @Type(type = "org.jadira.usertype.dateandtime.threeten.PersistentZonedDateTime")
    private ZonedDateTime modificationTime;

    @Column(name = "title", nullable = false, length = 100)
    private String title;

    @Version
    private long version;
	
	//The constructor, builder, and other methods are omitted
}

We are now ready to create our first Spring Data JPA repository. We can create the repository that provides CRUD operations for Todo objects by using one of the following methods:

  1. Create an interface that extends the CrudRepository interface.
  2. Create an interface that extends the Repository interface and add the required methods to the created interface.

Let’s take a closer look at these methods.

Extending the CrudRepository Interface

If we create our repository by extending the CrudRepository interface, we have to provide two type parameters:

  1. The type of the entity that is managed by our repository.
  2. The type of the entity’s id field.

In other words, when we create the repository that provides CRUD operations for Todo objects, we have to provide the following type parameters:

  1. The type of the entity is Todo.
  2. The type of the entity's id field is Long.

The source code of the TodoRepository interface looks as follows:

import org.springframework.data.repository.CrudRepository;

interface TodoRepository extends CrudRepository<Todo, Long> {

}

The CrudRepository interface declares many methods, but the methods that are relevant for this blog post are described in the following:

The service class that provides CRUD operations for todo entries uses these methods for fulfilling its responsibilities.

Let’s find out how we can create a repository interface that extends the Repository interface.

Extending the Repository Interface

If we create our repository by extending the Repository interface, we have to follow these steps:

  1. Provide two type parameters:
    1. The type of the managed entity (Todo).
    2. The type of the entity’s id field (Long).
  2. Add the required methods to the repository interface:
    1. The void delete(Todo deleted) method deletes the Todo object given as a method parameter.
    2. The List<Todo> findAll() method returns all Todo objects that are found from the database.
    3. The Optional<Todo> findOne(Long id) method finds the todo entry whose id is given as a method parameter. If no todo entry is found, this method returns an empty Optional.
    4. The Todo save(Todo persisted) method saves the Todo object given as a method parameter and returns the persisted object.

The source code of the TodoRepository interface looks as follows:

import org.springframework.data.repository.Repository;

import java.util.List;
import java.util.Optional;

interface TodoRepository extends Repository<Todo, Long> {

	void delete(Todo deleted);

	List<Todo> findAll();

	Optional<Todo> findOne(Long id);

	Todo save(Todo persisted);
}
If we don't want to return Optional (Guava / Java 8) objects, we can also use the "traditional" Todo findOne(Long id) method.

Additional Reading:

Let’s move on and find out which method we should use.

Which Method Should We Use?

It depends.

I know that this is probably the most annoying answer one can give to a question. That is why I created two rules that we can follow when we are creating Spring Data JPA repositories. These rules are:

  • If we want to expose all repository methods that are declared by the CrudRepository interface AND we don’t want to return Optional (Guava / Java 8) objects, our repository interfaces should extend the CrudRepository interface.
  • If we don’t want to expose all repository methods that are declared by the CrudRepository interface OR we want to return Optional (Guava / Java 8) objects, our repository interfaces must extend the Repository interface.

Case closed?

Not exactly. I argue that we should always use the second method. This opinion is based on two reasons:

  • When we create an interface, we should not add unnecessary methods to it. We should keep the interface as small as possible because small interfaces are easier to use and they help us to create components that have only one job.
  • Optional helps us to create better APIs because it reveals that there might not be a return value.

If we create our repositories by extending the Repository interface and adding the required methods to the created repository interfaces, we need to add the "same" methods to every interface. Right?

Wrong.

We can avoid this by following these steps:

  1. Create a base interface that extends the Repository interface and add the common methods to that interface.
  2. Create the actual repository interface that extends our base interface.

Let’s move on and take a closer look at these steps.

First, we have to create a base interface that declares the methods shared by our repositories. We can do this by following these steps:

  1. Create the BaseRepository interface that extends the Repository interface. This interface has two type parameters:
    1. T describes the type of the managed entity.
    2. ID describes the type of the entity’s id field.
  2. Annotate the created interface with the @NoRepositoryBean annotation. This ensures that Spring Data JPA doesn’t try to create an implementation for our base repository interface.
  3. Add the common methods to the created interface.

The source code of the BaseRepository interface looks as follows:

import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.Repository;

import java.util.List;
import java.util.Optional;

@NoRepositoryBean
interface BaseRepository<T, ID extends Serializable> extends Repository<T, ID> {

	void delete(T deleted);

	List<T> findAll();
	
	Optional<T> findOne(ID id);

	T save(T persisted);
}

Second, we have to create the actual repository interface that extends our base interface. We can do this by following these steps:

  1. Create the TodoRepository interface.
  2. Extend the BaseRepository interface and provide two type parameters:
    1. The type of the managed entity is Todo.
    2. The type of the entity’s id field is Long.

The source code of the TodoRepository interface looks as follows:

interface TodoRepository extends BaseRepository<Todo, Long> {

}

We have now created a repository hierarchy that allows us to:

  • Create repositories that provides CRUD operations for entities without declaring the "same" methods in every repository interface.
  • Create repositories that do not provide all CRUD operations. For example, we can create a repository that provides only the findAll() method.

The following figure illustrates the benefits of this solution:

springdatajpabaserepository

Let’s move on and summarize what we learned from this blog post.

Summary

This blog post has taught us three things:

  • We can create repository interfaces by extending either the CrudRepository or the Repository interface.
  • We should create our repositories by extending the Repository interface and adding the required methods to the created repository interface.
  • If our application has more than one repository, we should create a base repository interface that declares the methods that are shared by our "concrete" repositories.

The next part of this tutorial gives an introduction to query methods.

P.S. You can get the example application of this blog post from Github.

If you want to learn how to use Spring Data JPA, you should read my Spring Data JPA tutorial.
185 comments… add one
  • Kononen Jan 27, 2012 @ 9:46

    Great stuff.

  • Chris Feb 23, 2012 @ 15:52

    Hello,

    Thanks for your article. But where is the controller.createRedirectViewPath(REDIRECT_PATH) method in the net.petrikainulainen.spring.datajpa.controller.AbstractControllerTest class?

    Best regards.

    Chris

    • Petri Feb 23, 2012 @ 16:06

      Hi Chris,

      it is good to hear that you liked the article. The method you mentioned is found from the net.petrikainulainen.spring.datajpa.controller.AbstractController class. The AbstractControllerTest class declares the inner class called TestController only because the AbstractController class is abstract and it cannot be instantiated.

  • Rance moest May 18, 2012 @ 13:46

    Why bother with dtos? I thought that was ejb 2 nonsense

    • Petri May 22, 2012 @ 20:10

      Hi Rance,

      Thanks for your comment. I prefer using DTOs as form objects from following reasons:

      1) Since the transaction boundary is on the service layer, the model object is no longer associated with the persistence context when the transaction ends (unless you use an extended persistence context but that is an another story). This means that if you are using them as a form objects, you will have to synchronize its state with the database. Even though you "can" use the merge() method of the EntityManager interface, it can be PITA, and a source of interesting features. Thus, I prefer to avoid this if possible.

      2) The domain model should not be designed to make sense as a form object. It should be designed and implemented to make sense in the context of its domain. Also, you have to often make some ORM related compromises. This means that the building forms by using entity classes as form objects can be cumbersome. It is often easier to use DTOs even though it is not so "sexy".

      3) Often you have to add validation related metadata to the form objects. Adding these annotations to an entity object will object produce messy outcome, since entities are already annotated with JPA related annotations.

      I know that using DTOs as form objects means that I have to write some boilerplate code. However, it helps me to isolate the different layers of my software and to avoid weird features, which are sponsored by the used ORM.

      • Marco Jul 26, 2013 @ 11:12

        Hi.

        First of all congratulations for your blog and for the tutorials that you post, they are very interesting and useful! I've also read your Spring Data book, and I have found this page that your are the author :) !

        I've reached this page searching google for DTO. So my problem is more related to usage of DTO than to the usage of JPA, but if you have few minutes to spare, I would make you my question.

        Most likely you have had to deal with applications where the same domain Entity must be able to be modified by users with different privileges, and depending on the user privilege, only a subset of the fields could be editable.

        I think that it is one of the case where usage of DTOs make sense!

        In my case I have a Job entity that can be modified by different user with different roles, and based on the role only some field can be modified.

        So my question: a good approach could be to define an entity related DTO for each user ROLE? (For example: JobAdminDTO, JobUserDTO, JobGuestDTO).

        So in MVC application controller, given the user role i create the correct DTO and pass it to the view. I think that could be a bit harder to handle the correct type of the object returned from the view..

        In your opinion, could it be a good approach?

        Thanks again and sorry if I've bored
        Marco

        • Petri Jul 26, 2013 @ 12:07

          Hi Marco,

          That is an interesting question because the requirement which you have to implement is quite common. As always, there are many ways to implement this requirement.

          You found the first one which often comes to mind (use different DTOs for different roles).

          This approach has four problems:

          1. You have to implement different DTOs for different roles. Creating different DTOs is a minor annoyance but the bigger problem is that you have to implement the logic which creates these DTOs.
          2. Each DTO must have a different view.
          3. You have to implement handling logic for each role specific DTO. This leads into a situation where you will have to implement several methods which are pretty much doing the same thing.
          4. When you add a new role to the system, you have to: create a new DTO, create a new view for the created DTO and implement the logic which processes the created DTO. It is a lot of work. On the other hand, if you are sure that new roles are not added very often, this is not a problem.

          The second option is to use the same DTO for all roles and limit the editability of the form fields by using the authorize tag of the Spring Security JSP tag library.

          You can also create a custom HandlerMethodArgumentResolver which makes it possible to add the logged in user as a method parameter to your controller method.

          This approach has two problems:

          1. The logic which handles the form submission must select the updated fields by using the user role of the logged in user. This means that the implementation can be quite complex.
          2. The code of your view can be quite complex because you have to add the authorization logic in it.

          There is also a third option but it might not be usable if you are implementing a "normal" Spring MVC application (no REST API) because it requires that you add several submit buttons to your page. This option is that you are create one form for the fields which are common for all users and one form per each user role.

          As you can see, this problem has no "right" answer. There are several ways to implement this requirement and each one has different pros and cons. However, I hope that was able to give you something to think about.

  • David Jul 7, 2012 @ 17:12

    Great tutorial, it really helped clear up some confusion I had. I have been playing with this code and i was wondering if you could show how to use Jersey REST instead of Spring MVC? I have not been able to replace the Servlet with the Jersey SpringServlet because of the need to load the context programatically (which I love how you did).

    I tried this in the DataJPAExampleInitializer but of course it failed:
    rootContext.addApplicationListener(new org.springframework.web.context.request.RequestContextListener());
    rootContext.addApplicationListener(new org.springframework.web.util.Log4jConfigListener());
    SpringServlet springServlet = new com.sun.jersey.spi.spring.container.servlet.SpringServlet();
    ServletRegistration.Dynamic dispatcher = servletContext.addServlet(DISPATCHER_SERVLET_NAME, springServlet);

    Any ides on how this might work?

    • Petri Jul 10, 2012 @ 14:29

      David,

      Thanks for your comments. It is good to hear that this tutorial was useful to you. Regarding to your problem:

      The attached source code does not set an url mapping for the springServlet. What kind of exception are you getting? Is it related to the missing url mapping?

      • David Jul 11, 2012 @ 5:19

        Petri,

        I was trying to use the Jersey Spring Servlet instead of the DispatchServlet. But two things convinced me to change my direction and stick with SpringMVC:

        1) Version 3.1.1 added much better REST support, which previous attempts were so kludgy I went with Jersey.
        2) While looking at the Jersey site for a solution, I see that they will be releasing 2.0 that will not be backwards compatible, and I really don't feel like rewriting my work for that in the near future.

        Thank you again for a great tutorial, and I look forward to learning how SpringMVC and JPA work together now.

        • Petri Jul 17, 2012 @ 11:31

          Hi David,

          I am happy to hear that you found an answer to your problem. Also, I agree that the REST support of Spring Framework is rather good at the moment.

          Please remember that you can use JPA with Spring Framework without using Spring Data JPA but that does not really make any sense if you can build your applications from scratch.

          On the other hand, if you are working with existing applications, you might not want to replace existing persistence layer with Spring Data JPA repositories.

  • Ramesh Jul 18, 2012 @ 5:57

    Hi Petri,

    Great articles on spring data jpa. One thing I noticed was the update method on the serviceImpl is not actually updating. I tested the code and the updates don't seem to get persisted. Am I making a mistake or is it really missing? Let me know. I am a bit confused because after so many views, none have pointed that one out.

    -Ramesh

    • Petri Jul 18, 2012 @ 11:37

      Hi Ramesh,

      Thanks for your feedback. Did you experience this issue when running my example application? The reason why I am asking this is that I just tested the example application (https://github.com/pkainulainen/Examples/tree/master/Spring/data-jpa/tutorial-part-two) and found out that updating the information of a person works on my computer (Yeah, epic excude). Anyway, if you are running this example application application and the update method does not work, could you let me know. Also, if you have made any changes to the code, could you paste them to Pastebin so that I can help you out.

      If you are trying to apply the principles mentioned in this blog entry in another application, ensure that when the update method is called, you are inside a read-write transaction. The save() method of the repository is not called in my example because all changes made to persistent objects are flushed back to the database when a read-write transaction is committed.

      • Ramesh Jul 21, 2012 @ 19:18

        Thanks for the reply Petri. I was not exactly trying out your example, but had followed your example in a sample project of mine. I've extracted the relevant pieces and loaded it into paste bin at http://pastebin.com/SMR9fbWV. I have the disable method as a part of the transaction. Please take a look and let me know. In the meantime, I will also test our your application as it is.

        • Petri Jul 22, 2012 @ 11:18

          Hi Ramesh,

          The codes you pasted in Pastebin seems fine to me. It would be helpful if you could answer to following questions:

          - Are you using Hibernate or some other persistence provider? Which version do you use?
          - Which version of the Spring Data JPA are you using?
          - Which transaction manager are you using?
          - Which database you are using?

          This would help me to replicate your environment which helps me to find the reason of your problem.

          • Ramesh Jul 25, 2012 @ 6:31

            Hi Petri,

            - Are you using Hibernate or some other persistence provider? Which version do you use?
            I am using hibernate 3.5.6
            - Which version of the Spring Data JPA are you using?
            1.0.3
            - Which transaction manager are you using?
            Spring's transaction manager
            - Which database you are using?
            HSQLDB

            I have the relevant parts of the POM in paste bin here http://pastebin.com/igSc1MK9

          • Petri Jul 25, 2012 @ 21:19

            Hi Ramesh,

            I tried changing the dependency versions of my example application to match yours, and updating the information of a person is working without calling the save() method of the PersonRepository. When you said that you are using Spring's transaction manager, were you referring to the JpaTransactionManager (I use it in my example application)?

          • Ramesh Jul 26, 2012 @ 15:59

            Hi Petri,

            I was not able to reply to your last comment. So doing it here. First, thank you for your patience and persistence in trying to find the cause. It rare to find people like that. In my case, I pretty much use the same configuration as yours, but I use XML instead of java for configuration. Relevant parts of my configuration are at http://pastebin.com/ix2v6hmY. I have not yet tried your exact application. I will do so tonight and update you.

            Thanks,
            Ramesh

          • Petri Jul 26, 2012 @ 16:21

            Hi Ramesh,

            It is always nice to do some detective work and solve interesting problems. :)

            I looked at the configuration, which you added at Pastebin, and it looked fine to me. However, have you enabled the annotation driven transaction management in your application context configuration file? If you are using XML, you can do this by adding the following line to your application context configuration (or by adding the @EnableTransactionManagement annotation to your application context configuration class):

            <tx:annotation-driven transaction-manager="transactionManager"/>

            More information about this is found at the reference documentation of Spring Framework 3.1.x:

            http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/htmlsingle/spring-framework-reference.html#transaction-declarative-annotations

  • Applebee Jul 27, 2012 @ 21:33

    Hi Petri,

    very nice tutorial, learning new things, very helpful.

    can you just show how to block crud operations.
    I created one entity and repository using spring-data-Jpa extending CrudRepository. But I dont want to allow CRUD operations, I need to block them. For in case if I want to delete any entry in database throu service I need to get an error code. Is there any way to block crud operations? Thanks

    • Petri Jul 27, 2012 @ 21:41

      Hi Applebee,

      I would use Spring Security to deny access to unwanted operations. Check out the homepage of the Spring Security project: http://static.springsource.org/spring-security/site/.

      • Applebee Jul 27, 2012 @ 21:47

        can you show with an example how to use Spring Security to deny access?

        • Petri Jul 27, 2012 @ 23:42

          Hi Applebee,

          The exact process is too long to be described in a comment but there are several Spring Security tutorials available on the internet. Here are few of them:

          • Applebee Jul 30, 2012 @ 18:54

            Hi Petri,

            Thanks for your reply. I have one more question, from the above Person example

            when I created the PersonRepository I added one method findByFirstName which I am able to get the results. Here I don't want to add findBy for other attributes.

            So when I was trying to search with other attibutes it is giving 500 Internal Server Error. Is there any way to customize that kind of exceptions.

            Thank you.

          • Petri Jul 30, 2012 @ 20:09

            Hi Applebee,

            If you are talking about the exceptions that are thrown by Spring Data JPA or Spring Framework, it is not possible to customize them without changing the source code of the framework in question.

            However, it is possible to configure an exception handler that specifies the view that is rendered when a specific exception is thrown. More information about this is found from the reference manual of Spring Framework:

            http://static.springsource.org/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-exceptionhandlers

            Also, I would probably use the approaches described in later parts of my Spring Data JPA tutorial for implementing the search function you mentioned. Using the query generation from method name strategy for this purpose is not very user friendly because is not possible to implement a case insensitive search with it.

      • Jagadish May 17, 2014 @ 16:03

        Hi Petri,
        this is Jagadeesh i am developing one web application in which i am using spring mvc4.0 and spring data jpa .In this application i am developing simple registration page which contains fields of three entities now, the problem is how to insert data into three tables or three entites by form submission of registration page.Along with i am having small doubt i.e. in JPA we are having save() which meant for saving data into database
        but for updating data is their any default method in JPA?
        The above are the two problems which i am facing from few days onwards
        if Know please help me to get rid of this problem
        Thanks&Regards
        jagadeesh

  • Applebee Aug 3, 2012 @ 22:17

    Hi Petri,

    I have a database view "Example"

    Example
    id name
    --------------------
    100 HELLO
    100 HELLO WORLD
    200 TEST
    200 TEST123
    300 APPLE

    Created entity and repository for Example using JPA Annotations
    Entity: Example.java and the repository class ExampleRepository extends CrudRepository

    HTTP GET to the application:

    localhost:8080/data

    {
    "_links" : [ {
    "rel" : "data",
    "href" : "http://localhost:8080/data/data"
    } ]
    }

    localhost:8080/data/data

    {
    "_links" : [ {
    "rel" : "data.Example.100",
    "href" : "http://localhost:8080/data/data/100"
    }, {
    "rel" : "data.Example.100",
    "href" : "http://localhost:8080/data/data/100"
    }, {
    "rel" : "data.Example.200",
    "href" : "http://localhost:8080/data/data/200"
    }, {
    "rel" : "data.Example.200",
    "href" : "http://localhost:8080/data/data/200"
    }, {
    "rel" : "data.Example.300",
    "href" : "http://localhost:8080/data/data/300"
    }, {
    "rel" : "data.search",
    "href" : "http://localhost:8080/data/data/search"
    } ]
    }

    Is there any way I can search using multiple parameters like
    localhost:8080/data/data/search/id?id=(100,200)

    or using IN operator

    Thanks

    • Petri Aug 4, 2012 @ 20:43

      Hi Applebee,

      One comment about your web layer:

      I would consider using POST and sending the search conditions as JSON in the request body. This makes a lot more sense than your current approach since it seems that you want to send 0..* ids to your controller method.

      About the query creation:

      I would use Querydsl or the JPA Criteria API to build the actual query. If you have no experience from these techniques, you might want to check out these blog entries:

      However, the creation of a query that uses the IN operator is not described in those entries. I managed to find one article that has an example of the usage of IN operator and the JPA Criteria API: Dynamic, typesafe queries with JPA 2.0.

  • Marc R. Sep 21, 2012 @ 7:42

    Hi Petri,

    Your tutorial is honestly the best source of information about Spring Data right now, you are also very good at explaining everything.

    Unfortunately, I recently encountered a problem and didn't really figured out any easy way to deal with it.

    Let's say you want to add the following Column to Person.java
    @Column(name = "Alias", unique = true)
    private String alias;

    How would you ensure the Uniqueness of this alias. So far, adding a custom validator that check for unicity using a query at the DTO level doesn't really solve the problem as any concurrent transaction could modify data after a manual check but before the commit of the ongoing transaction. And secondly, as I'm not using @Validator on the Entity itself but on the DTO, there's isn't any straightforward way to get the errors and feed it back to my view.

    Any idea on how to solve this problem?

    Thank you

    • Petri Sep 21, 2012 @ 10:25

      Hi Marc,

      It is good to hear that you like my tutorial. About your problem:

      This is indeed a tricky one since you cannot really know whether a unique constraint is broken until you save the entity to the database (I am assuming that you have got unique constraint for the Alias column at database). There are some useful pointers at stackoverflow:

      It seems that there is no elegant and portable way to handle this. However, we can do something about it. I would try to minimize the chance that the unique constraint is broken by following these steps:

      1. Implement a controller method that processes Ajax requests and finds out if a certain alias is free. This controller method would be used to do some client side validation (or to provide a check availability function).
      2. When a new person is added, I would check the availability of the alias at the controller method that processes the request. This way I can add an error to the BindingResult object if the alias is already in use.
      3. As you pointed out, this does not solve a situation where a concurrent transaction modifies the data after the alias has been checked manually but before the ongoing transaction is committed. The third step would be to take of this problem. I would probably catch the exception that is thrown when the unique constraint is broken and add an error to the BindingResult object. However, finding out the cause of the exception can be ugly as explained in the links that I pasted before.

      What do you think about this solution?

  • don Sep 24, 2012 @ 16:49

    Petri,

    Thanks for the wonderful tutorials!

    It is not rare for real-world application to involve a couple of hundred database tables. Normally we would use code-generation tools such as Jboss Tools to reverse-engineer an existing database and automatically generate entity classes and JPA annotations. The Person class in your tutorial is highly customized. How do you generate that kind of customized code if you have to deal with a couple of hundred tables?

    • Petri Sep 24, 2012 @ 23:02

      Hi Don,

      It was nice to hear to that you like my tutorials. Also, I want to thank for an excellent question.

      Unfortunately, as far as I know, there is no way generate "customized" domain model classes automatically. As you said, one can use code generators to generate entities from an existing database but typically this leads in to a anemic domain model. For a quite long time I was writing applications that used this approach and I was perfectly happy with it.

      However, then I read a book called Domain Driven Design and saw the light. The problem with my old approach was that I kind of got all the problems caused by object-relational mismatch and got none of the benefits. All my business logic was scattered around the service layer, which made my service classes look like a mess. Now, when I moved the business logic from the service layer to the domain model, I got the following benefits:

      • The service layer is clean and it is responsible of application logic.
      • All business logic is put into a single place: to the domain model. This way I always know where I can find it. I don't have to search it from a messy service layer anymore.
      • Structuring the code this way makes it easier to write GOOD unit tests for it.

      Because of these benefits I am ready accept that I will spend a lot of time working with my domain model. Also, since I have been mostly participated in software development projects that uses Agile methods, the implementation and design of the application is divided in to sprints so I never have to face the horrible task of fixing the whole domain model at once (As you stated, it would be a huge task since the databases of real world applications tend to have a lot of tables).

  • Mladen Oct 22, 2012 @ 16:49

    Why is it so difficult to write package statements in the code?
    some libraries is not in the initial pom file e.g. apache lang commons

    • Petri Oct 22, 2012 @ 17:08

      Hi Mladen,

      I left the import statements out because I felt that including them would make this blog entry too long. Also, since I have included a fully functional example application, I thought that adding them would add little value. It seems that I might have rethink my attitude and add import statements (I will leave the obvious ones out though) to the code samples that are attached to my blog entries. This might take some time so be patient. :)

      Regarding to your second point, the pom file of my example application declares all the required dependencies (including commons lang).

  • Mildo Nov 5, 2012 @ 2:02

    Hi Petri,

    Great tutorial!! Excellent Job!! I'm having some trouble running the tutorial on Tomcat could you guide me on how to migrate it from jetty to tomcat? I tried removing the webdefault.xml and writting an new web.xml but it isn't working the Spring context is not beeing loaded.

    Thanks in advance

    Mildo

    • Petri Nov 5, 2012 @ 10:21

      Hi Mildo,

      Thanks for your comment. It is nice to know that you like this tutorial.

      Are you trying to deploy the created war file directly to Tomcat or are you using the Tomcat Maven plugin? The webdefault.xml file is required only because the sample project is using an old version of the Jetty Maven plugin. I should probably update this plugin and remove the unnecessary files from the sample project.

      Update: Check this comment out if you are using Tomcat 6.

  • Vipul Popat Nov 6, 2012 @ 12:37

    Hi Petri

    Thanks for the wonderful article but cannot deploy the example on tomcat
    Can you please send me a web.xml for tomcat asap

    Regards
    Vipul

    • Petri Nov 6, 2012 @ 12:56

      Hi Vipul,

      Thanks for your comment!

      This example requires that a Servlet 3.0 compliant servlet container is used and it should work fine with Tomcat 7. If you are using an older version of Tomcat, you cannot configure your web application by using programmatic configuration. In other words, you have to delete the DataJPAExampleInitializer class and create a web.xml file. This process is explained in the following article:

      Bootstrapping a web application with Spring 3.1 and Java based Configuration, part 1

      Also, let me know if you are using Tomcat 7 and cannot deploy the example application.

  • Josh Dec 10, 2012 @ 5:59

    Petri,

    Perhaps I'm missing the advantage of using the builder pattern because of the simplicity of its use in the Person class, but it doesn't seem like it is buying you anything more than a straight constructor or a static method would. Instead by using it you have to construct an extra object and make an extra call.

    What am I missing?

    • Petri Dec 10, 2012 @ 20:15

      Hi Josh,

      you are right. In this example the builder pattern is definitely an overkill and it would be better to use a regular constructor. However, I used it on this example because wanted to emphasize that it is a good way to create new objects (especially when the created object has a lot of optional parameters). The alternatives of the builder pattern are:

      • The first option is to use the telescoping constructor pattern to create objects that have multiple optional parameters. This means that you up writing many constructors (the actual amount depends from the number of optional parameters). This has two disadvantages: it is hard to create objects (especially if the parameters have the same type), and the code becomes really messy and hard to read. However, this approach is one advantage: it ensures that your code is thread safe.
      • The second option is to use so called Javabeans style construction. The problem with this approach is that even though the resulting code is quite easy to read, the created object is in inconsistent state during its creation and it prevents you from making your class immutable. Also, you have to manually ensure that your code is thread safe.

      The builder pattern combines the safety of the telescoping constructor pattern and the readability of the Javabeans style construction. That is why it should be used on model objects unless you have a REALLY good reason not to use it.

      • Josh Dec 12, 2012 @ 8:54

        So, perhaps the issue I'm having in seeing the applicability is that all of the main fields in the Person object are required. How does this pattern take care of the telescoping constructor pattern for optional parameters? Say you add height, weight, and hairColor to Person. Do you just end up with telescoping parameters in your builder object? Or do you construct the object with the builder and then resume using the setters for the rest?

        When I searched for the pattern online the applicability seemed to center on complex construction tasks, like in the cases where object creation involves the coordination of several other objects or involves some tricky sequencing.

        Thanks

        • Petri Dec 12, 2012 @ 9:18

          Hi Josh,

          Optional properties are dealt with by creating so called property methods that are used to set the optional parameters. Here is the source code of the Person class that has the optional parameters you suggested:

          public class Person {
             
              private String firstName;
              private Color hairColor;
              private int height;
              private String lastName;
              private int weight;
              
              //This sucks but it is required by Hibernate
              public Person() {
              }
          
              //Getters and other methods. No Setters
          
              public static Builder getBuilder(String firstName, String lastName) {
                  return new Builder(firstName, lastName);
              }
          
              public static class Builder {
                  Person built;
          
                  Builder(String firstName, String lastName) {
                      built = new Person();
                      built.firstName = firstName;
                      built.lastName = lastName;
                  }
          
                  public Builder hairColor(Color hairColor) {
                      built.hairColor = hairColor;
                      return this;
                  }
          
                  public Builder height(int height) {
                      built.heigth = height;
                      return this;
                  }
          
                  public Builder weight(int weight) {
                      built.weight = weight;
                      return this;
                  }
          
                  public Person build() {
                      return built;
                  }
              }
          }
          


          Here are some examples that illustrate the usage of these property methods:

          //Only mandatory properties are set
          Person onlyMandatory = Person.getBuilder("John", "Smith").build();
          
          //Sets first name, last name and hair color
          Person blonde = Person.getBuilder("Jane", "Smith").hairColor(Color.YELLOW).build();
          
          //Creates new person and sets the values of all properties
          Person person = Person.getBuilder("John", "Smith")
          		.hairColor(Color.BROWN)
          		.height(100)
          		.weight(100)
          		.build();
          


          I hope that this example answered to your question.

          • Josh Dec 16, 2012 @ 21:47

            Thanks, yes that helps. So from your latest example I can see where you could put some integrity checks in the build() method allowing you to ensure that the optional attributes are set consistently with each other before giving access to the Person object. However, I can also see where you would need to be careful with this pattern as your objects could easily become immutable or very difficult to update without client classes also maintaining a reference to the builder that created the object in the first place.

          • Marco Nov 28, 2013 @ 11:55

            what is difference bettween setId(String id) and id(String id)
            is the second method so helpfull ?

          • Petri Nov 28, 2013 @ 20:27

            You should take a look at the blog post titled: The builder pattern in practice. It provides a very nice explanation of the builder pattern and describes its benefits as well.

          • Belden Jun 7, 2014 @ 7:56

            Hi Petri,

            I want to thank you for creating such an excellent post! This series has definitely given me a good introduction to Spring Data JPA.

            I'm comparing your Builder pattern with how it's demonstrated in the book, 'Effective Java', by Joshua Bloch. One difference I notice is that you don't re-define the properties within the nested 'Builder' class. Is the way you are doing it a cleaner technique because you don't have to re-define the properties again (once in the 'Person' class and then once again the nested 'Builder' class)?

            Also, I've heard that one advantage of the a Builder class is that it can be immutable, however, I notice you have an 'update' method, a 'preUpdate' method, and some other methods that effectively update the class after it's been instantiated. Wouldn't this break the contract of it being an immutable class? Or is there no way around this and you need these "updating" methods because of how Spring Data JPA works? Instead of these "updating" methods, could you create a new 'Person Object' with the new properties it needs and use that as the new updated object somehow?

          • Petri Jun 7, 2014 @ 11:47

            Hi Belden,

            it is good to hear that this tutorial has been useful to you. I will answer to your questions in the following:

            "Is the way you are doing it a cleaner technique because you don’t have to re-define the properties again (once in the ‘Person’ class and then once again the nested ‘Builder’ class)?"

            Yes. That was my original reason for doing this. However, this approach has a serious drawback: you cannot really create immutable objects because you cannot use the final keyword in the fields of the created class. That is why I have abandoned my approach and started using the approach described by Joshua Bloch. The reason why I haven't updated my old blog posts is that it would take too much work.

            Also, I’ve heard that one advantage of the a Builder class is that it can be immutable

            Yes. That is one advantage of the builder patter. Another advantage is that you can create a domain-specific language for building new object.

            however, I notice you have an ‘update’ method, a ‘preUpdate’ method, and some other methods that effectively update the class after it’s been instantiated. Wouldn’t this break the contract of it being an immutable class?

            Yes.

            Or is there no way around this and you need these “updating” methods because of how Spring Data JPA works? Instead of these “updating” methods, could you create a new ‘Person Object’ with the new properties it needs and use that as the new updated object somehow?

            The problem is that if you use an ORM tool, it means that entities must be mutable (e.g. Hibernate requires that each entity has a default constructor). However, you can reduce mutability by using immutable value types (@Embeddable classes). I try to move as much information as I can to value types because this way I can minimize the effects of mutability.

  • Jan Dec 10, 2012 @ 17:08

    Hi,

    First of all a big thank you - this is the tutorial I have been looking for, great job!

    I do have one issue. I guess it is a configuration issue (or a stupid typo I did as it works for everyone else). I created my own application using yours as a template. I use tomcat 7, I start it from Eclipse (Juno).

    Server starts without issues at http://localhost:8080/myapp/ and shows me the list of records I put in the database.

    As soon as I click any of the links, my url becomes:
    http://localhost:8080/person/edit/2

    ... which does not exist (is your app designed to run as ROOT.war in Tomcat by any chance?)

    As soon as I change the URL to http://localhost:8080/myapp/person/edit/2, I get to the edit view.

    However, all the links on the edit page change either to
    http://localhost:8080/ (back)
    or
    http://localhost:8080/person/edit (save)

    so needles to say, both save and back do not work.

    To sum it up: How do I change the configuration when using Java configuration in Spring so that I can deploy your application just like I did?

    Thank you,
    Jan

    • Petri Dec 10, 2012 @ 20:37

      Hi Jan,

      Good to hear that you liked this tutorial.

      I have to confess that I was a bit lazy when I created the user interface of the example application. Like you suspected, the links are working correctly only if the context path of the application is '/'.

      Luckily, this problem should be pretty easy to fix: You can use the url tag to construct an url that contains the context path. Check out this StackOverflow question for more details about this: how to use <spring:url /> with an <a> tag?

      • Jan Dec 10, 2012 @ 20:48

        Hi Petri,

        Thank you for your quick answer. I will try the solution first thing in the morning tomorrow. I got a bit rusty on the subject of creating a new project from the scratch ... and in the meantime the world has changed ;-).

        Oh I would not dare to call you lazy after all the tutorial parts you published and after answering all the questions on your page!

        If you ever come to Holland, I owe you a beer ;)

        Regards,
        Jan

        • Petri Dec 11, 2012 @ 9:28

          Jan,

          I have to come to visit Holland then!

          About the fix, let me know if it did the trick. I know at least one other way to fix this but that fix is kind of ugly. That is why I did not suggest it as the first option.

  • MiB Jan 15, 2013 @ 23:08

    Excellent article. It got me interested in your book. I can't import part five, six and eight of the source code as there's an error when setting up maven plugin connectors in Eclipse Juno ( SpringSource Tool Suite 3.1): "No marketplace entries found to handle /pom.xml in Eclipse."

    I installed m2e-apt from Jboss. This is not enough? Anyone know?

  • MiB Jan 16, 2013 @ 7:16

    I had to replace the bean definition in applicationContext.xml:

    and update Spring Data Jpa to 1.2 in the pom in order to avoid the error "sch.props.correct.2: A schema cannot contain two global components of the same name" in Springsource Tool Suite.

    "Spring Data- JPA Schema validation error in STS" https://jira.springsource.org/browse/DATAJPA-160

    • Petri Jan 16, 2013 @ 9:10

      MiB,

      Good to hear that you were able to solve your problem. Also, if you want to get rid of the XML configuration file which is used to configure Spring Data JPA, you can simply add the @EnableJpaRepositories annotation (supported in Spring Data JPA 1.2) to your application context configuration class and delete the XML configuration file.

  • MiB Jan 16, 2013 @ 13:12

    Well, I also had to set m2e to ignore execution of the maven-apt-plugin.
    I got this classic before that:
    "Plugin execution not covered by lifecycle configuration: com.mysema.maven:maven-apt-plugin:1.0.2:process (execution: default, phase: generate-sources)"

    Then run that generate-sources phase, set source folder, then clean build. For some reason in some cases — Part five I think — I had to run the tests as junit tests and not maven tests in order for them to run green.

    • Petri Jan 16, 2013 @ 14:03

      Unfortunately the Maven APT plugin does not work very well with Eclipse. However, at least one of my readers has managed to configure it. See the comment written by Eric B for more details.

  • MiB Jan 16, 2013 @ 14:15

    Thanks!

    • Petri Jan 16, 2013 @ 14:17

      You are welcome.

  • Philipp Mar 13, 2013 @ 13:34

    Thank you very much for your tutorials!

    I'm currently digging into Spring Data, Hibernate and JPA. The goal is to build a simple application that involves Wicket for web logic and Spring Data for easy persistence support. I'm struggling a bit with configure Spring Data outside of a Spring MVC context: What configuration files are relevant and where to put them? For example you named you applicationContext-persistence.xml instead of just applicationContext.xml. Does this have impact on how the file is handled? Do you have examples for how to use Spring Data outside of a Spring MVC application? Do I have to understand the whole Spring framework at the end or is it possible to use just a potion of the framework without getting to much invovled with the others?

    Furthermore, I learn a lot about application infrastructure and patterns just by reading your comments. Thank you for sharing your expertise!

    • Petri Mar 13, 2013 @ 20:14

      The example application configures the Spring application context by using a combination of Java and XML configuration. This approach is described in the first part of my Spring Data JPA tutorial.

      I have also written a comment to that blog entry which describes how you can configure Spring Data JPA, Hibernate and Spring transaction management by using XML configuration.

      I guess the question is: Do you want to configure your application context by using Java configuration or XML configuration files?

      About Wicket and Spring Data:

      Unfortunately, all my Spring Data examples use Spring MVC. However, I have used Spring with Wicket (1.4.x) in the past and I think that I can give you some pointers which should help you to get started:

      I hope that this answered to your question. If you have any other questions, feel free to ask them!

  • Ankit May 16, 2013 @ 22:13

    Hi Petri,
    Your example is very good for beginners to start with as an console based application. Can u give me simple example of Spring Data JPA with MVC integration using MySql and Maven.
    If u can help me out in this , it would be great help for me

    Thankxxxx

    • Petri May 17, 2013 @ 15:16

      Hi Ankit,

      You can enable the MySQL support of the example application by following these steps:

      1. Remove the H2 database dependency from the pom.xml file.
      2. Uncomment the MySQL connector dependency declaration found from the pom.xml file.
      3. Open the application.properties file and set the used JDBC driver, database url and Hibernate dialect. This file contains valid MySQL configuration which is commented out by default. In other words, all you have to do is to remove the H2 configuration and enable the MySQL configuration.

      I hope that this answered to your question.

  • Agung Setiawan May 29, 2013 @ 12:52

    Hi Petri, great tutorial to begin the journey of Spring Data JPA :D
    i see your code in the Github and there's no Unit Test for Repository class
    my assumption is because it is part of the framework, so we just can trust the author lol
    if we want to test how can we do it, i didn't see you write the implementation of the Repository interface

    thanks,

    • Agung Setiawan May 29, 2013 @ 12:58

      wupss i meant Integration Test

      • Petri May 29, 2013 @ 13:07

        I answered your original comment before I saw this comment. :)

        Anyway, check out my answer to your original comment. It has an link to an example application which has integration tests for its repository interface.

    • Petri May 29, 2013 @ 13:04

      Hi Agung,

      Thank you for your comment.

      The reason why there is no unit test for the repository interface is that when you are using Spring Data JPA, you don't have to implement your repository interfaces. Spring Data JPA is capable of providing an implementation for them as long as your repository interfaces extends one of the "special" interfaces of Spring Data. The base interface of these "special" interfaces is the Repository interface.

      You can however write integration tests to your repository interfaces. I have been planning to write a blog post about for some time now. Perhaps I should do it in the near future?

      In the meanwhile, you can check out the example application of my blog post which describes how you can use Querydsl in a multi-module Maven project. This application has integration tests for the repository interface.

      Update: I took look at the project and it seems that I wrote integration tests for the service implementation. You can, however, use the same technique when you are writing integration tests for your repositories. It seems that I should probably write a blog post about this soon.

      I hope that this answered to your question.

  • HAIKI MONCEF Jun 26, 2013 @ 15:34

    HI ,
    great work there , i'm new to webapps i was wondering how can i deploy this application on jboss 7.1.0 as

  • Bowen Jul 11, 2013 @ 17:13

    Hello Petri, you are really a great writter. Like every one else, I have seen a lot of tutorial websites, however, you are the only person who literally replies to every single comment. I greatly admire your spirit. Wish you have even greater success on your future career.

    • Petri Jul 11, 2013 @ 18:25

      Hi Bowen,

      Thank you for your kind words. I really appreciate them.

      Yes, I like to reply to every comment I get (especially if there is a question) because I feel that it makes no point to give a reader the possibility to comment your blog posts unless you are willing to communicate with them.

      I think that the comments I get are valuable in two ways:

      1. They might reveal a problem in my blog post. These comments are extremely valuable because I can avoid making the same mistake in the future. Also, I get a chance to fix the original blog post.
      2. They force me to look the solved problem from a different perspective. Again, this is a good thing because usually I learn something new during the process.

      I wish you all the best in your future career as well!

  • WS Aug 14, 2013 @ 23:31

    Hi Petri, I've followed this tutorial (thanks a lot) and everything worked perfectly until I added a one-to-many relationship. I'm encountering an EntityNotFoundException and just can't figure it out. I've tried so many different methods, but still stuck. Posted a question on stackoverflow if you have time to check it out. Thanks. http://stackoverflow.com/questions/18237689/hibernate-4-2-onetomany-entitynotfoundexception/

    • Petri Aug 15, 2013 @ 8:47

      It seems that you found the answer to your question while I was sleeping (based on the StackOverflow question). Am I correct?

  • WS Aug 15, 2013 @ 16:28

    Petri, it appeared to be working but ran into an issue after I added subsequent records. The primary key on the keywords table is text in my solution, but I wanted it to be the docid. Didn't realize that until I had duplicate keywords in other documents. Any ideas?

    • Petri Aug 15, 2013 @ 17:21

      So your problem is that you cannot add new documents because the same keyword appears in more than one document?

      You have to add a new field to the Keyword class and use that field as the id of the entity. You cannot use the docid column as the private key because this means that you could add only one keyword per document (private key has to be unique).

      • WS Aug 15, 2013 @ 18:01

        That's right, each `Document` could have similar keywords. Last night I experimented with a `kywd_id` on the `Keyword` class, but then the keywords were duplicated on updates. `kywd_id` was auto-incrementing.

        Say `Document` has keywords: one, two, three. And the `docid` is `abcd`.

        Then the table rows looked like,

        1, one, abcd
        2, two, abcd
        3, three, abcd

        If I added a new keyword to `abcd`, then the table looked like,

        1, one, abcd
        2, two, abcd
        3, three, abcd
        4, one, abcd
        5, two, abcd
        6, three, abcd
        7, four, abcd

        I'm expecting,

        1, one, abcd
        2, two, abcd
        3, three, abcd
        4, four, abcd

        If I added a new document `efgh` and it has the same keywords, I'd expect the table to have,

        1, one, abcd
        2, two, abcd
        3, three, abcd
        4, four, abcd
        5, one, efgh
        6, two, efgh
        7, three, efgh
        8, four, efgh

        I can't figure out the primary keys or constraints for this scenario. I was thinking the keywords table could have a unique constraint on `docid` and `text` and both be primary keys.

        • WS Aug 15, 2013 @ 19:02

          Something I just realized might not be handled automatically is if we remove keywords from a document.

        • Petri Aug 15, 2013 @ 19:45

          I assume that you are not loading the document (and its keywords) from the database when you are updating it?

          Because the Keyword objects of your document are transient, new rows are added to the database.

          You don't get duplicate documents because the your Document has a docid (I assume that you read it from the XML file). The repository implementation notices this and calls the merge() method of the EntityManager class instead of the persist() method.

          I recommend that you you follow this approach (inside a read-write transaction):

          1. Load Document object from the database.
          2. If no document is found, save a new object.
          3. If a document is found, update this object instead of saving the object which you created from the XML file.
  • WS Aug 15, 2013 @ 21:48

    That sounds like a nice approach. One question before I get into that. On `Document` I have, @JoinColumn(name = "docid_fk"). Is there any way to make `docid_fk` and `text` both primary keys on `kywd_t` since `docid_fk` isn't directly defined on `Keyword`?

  • WS Aug 15, 2013 @ 23:34

    I'd rather not make it unnecessarily complex if possible. Seems many people agree with you too. Right now I'm tinkering with a @JoinTable but it has some issues as well.

    In `Document`,

    @OneToMany(cascade = CascadeType.ALL)
    @JoinTable(
    name = "mtdt_kywd_t",
    joinColumns = {
    @JoinColumn(name="docid", referencedColumnName="docid", unique = true)
    },
    inverseJoinColumns = {
    @JoinColumn(name="text", referencedColumnName="text")
    }
    )
    @XmlPath("head/meta/kb:keywords/kb:keyword")
    private Set keywords;

    And in `Keyword`,

    @OneToOne(cascade = CascadeType.ALL)
    @JoinTable(
    name = "mtdt_kywd_t",
    joinColumns = {
    @JoinColumn(name="text", referencedColumnName="text", unique = true)
    },inverseJoinColumns = {
    @JoinColumn(name="docid", referencedColumnName="docid")
    }
    )
    private Document document;

    I don't want to take anymore of your time, you've been most helpful. If/When I discover a solution I'll report back. Thanks Petri.

  • WS Aug 16, 2013 @ 17:47

    Petri, been working on this for quite a while with a coworker and he figured it out yesterday afternoon. Here's what we came up with.

    On `Document` we have,

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
    @OrderColumn
    @JoinColumn(name = "docid")
    @XmlPath("head/meta/kb:keywords/kb:keyword")
    private Set keywords;

    On `Keyword` we have an auto-generated id now,

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @XmlTransient
    private Long id;

    and,

    @ManyToOne
    @JoinColumn(name = "docid", insertable = false, updatable = false)
    @XmlTransient
    private Document document;

    Thanks again for the help.

    • Petri Aug 16, 2013 @ 18:47

      You are welcome! Also, it is great to hear that you could solve your problem.

  • Vikas Sep 26, 2013 @ 15:13

    Hello Petri,

    First of all I want to thank you for your excellent work here.. you are simply great. you explained things very simply.... I worked in Spring , Hibernate projects in 2006 / 2007 after that I had to work in a middleware Microsoft Biztalk sever. But recently I started looking my old old skills and happened to find your articles.
    I have some Questions to you. :-)

    Do we have any tools that support following sequence of development?
    1. Develop Database tables and relationships first using any tool.
    2. Then based on those tables auto generate Java entity classes and Service for CRUD operations
    3. Then Auto Generate the Skeleton for the controller classes.
    4. Then Auto generate Model/View for those CRUD operations.
    5. Then Build and Deploy.

    My aim is to generate an initial working web application skeleton with minimal or zero lines of java code manually. Later we can change and customize the auto generated code.

    Is this Possible Using Eclipse latest version? If so would it be possible to post the minimal sequence of steps that need to perform to make a working skeleton of REST full java web app. I

    Any help would be greatly appreciated.

    Regards
    Vikas

    • Petri Sep 26, 2013 @ 19:56

      You are welcome! I am happy to hear that I could help you get started again.

      You might want to check out the following projects:

      These are a bit different projects but they have the same goal: help you to get started as soon as possible.

      Based on your questions, Spring Roo might be what you are looking for. I haven't personally tried it out, but the reference manual of Spring Roo looks quite promising.

      Also, I think that Hibernate Tools can create domain model classes from an existing database.

  • Vikas Sep 27, 2013 @ 12:45

    Once again Thank you Petri .. I will explore these and see how fast we can develop
    Vikas

  • Katie Nov 13, 2013 @ 22:44

    Petri, I followed your steps in this post to set up my repository. But when I try to test it against real database, updated data wasn't actually reflected in database unless I call save. Any idea what could be the problem?

    • Petri Nov 13, 2013 @ 23:06

      Hi Katie,

      One possible reason is that your code is not executed inside a read-write transaction. Have you annotated your service method with the @Transactional annotation?

      The changes made to persistent objects should be updated back to the database as long as changes are made inside a read-write transaction. That is why you don't have to call the save() method when you are updating information inside a read-write transaction.

      Also, you might find want to read my blog post which talks about the integration testing of Spring Data JPA repositories.

      If this didn't solve your problem, please let me know. :)

  • Alicja Nov 14, 2013 @ 1:44

    Petri,
    I use your tutorial and it's very helpful but in my application I have to use postgresql and I don't know how to configure it. When I uncomment in your application parts about postgres (in pom and application.properties) it doesn't work. I start app, got info:
    'DEBUG - LogicalConnectionImpl - Obtaining JDBC connection'
    and nothing happens. Could you tell me what should I change to fix it?
    Thanks,
    Alicja

    • Petri Nov 14, 2013 @ 18:11

      If you want to use PostgreSQL, you have to make following changes to the example application:

      1. Remove the H2 database driver dependency from the pom.xml file.
      2. Uncomment the PostgreSQL driver dependency found from the pom.xml file.
      3. Change the configuration found from the application.properties file.

      If you want to use PostgreSQL, the database and Hibernate configuration found from the src/main/resources/application.properties file looks as follows:

      
      #Database Configuration
      db.driver=db.driver=org.postgresql.Driver
      db.url=jdbc:postgresql://localhost/datajpa
      db.username=username
      db.password=password
      
      #Hibernate Configuration
      hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
      hibernate.format_sql=true
      hibernate.hbm2ddl.auto=create-drop
      hibernate.ejb.naming_strategy=org.hibernate.cfg.ImprovedNamingStrategy
      hibernate.show_sql=true
      
      

      I hope that this answered to your question.

      • shahbaz Feb 14, 2017 @ 20:06

        Very good java tutorials for beginners

        • Petri Feb 15, 2017 @ 18:20

          Thank you for your kind words. I really appreciate them.

  • David Dec 7, 2013 @ 16:03

    Great blog and tutorials! How do you handle entities that have a lot of properties (5 or more)? The update method's parameter list gets too large in these cases and it seems having setters would be a bit cleaner.

    • Petri Dec 8, 2013 @ 22:29

      Thank your for your kind words. I really appreciate them.

      You are absolutely right. If entities have a lot of properties, having a single update method is not practical. Typically I separate the properties into value objects (e.g. Address and so on) and create a separate update method per value object.

      On other hand, if the properties are entities, I try to follow a pattern called aggregate. At the moment it seems to make perfect sense to me but I might change my mind after a few years or so (this happens).

      I hope that you find this answer useful.

  • Edward Beckett Jan 20, 2014 @ 4:12

    @Petri ... Awesome Job ... As Expected... ;-)

    FYI ... Running a modified version of this on Glassfish required me to implement Serializable on the DTO or I was getting Invalid Attribute errors .... FWIW ...

    Great Job Chief!!!

    • Petri Jan 20, 2014 @ 18:06

      Thank you for you kind words. I really appreciate them.

      Also, thanks for leaving a note regarding the Glassfish & Serializable problem. Maybe It will be useful to someone.

  • varun Feb 11, 2014 @ 17:22

    Hi Petri
    I have three entities like below

    1. CompanyInfo

    
    @Entity
    public class CompanyInfo {
    	@Id
    	@GeneratedValue
    	private long companyId;
    	private String companyName;
    
    	@OneToMany(mappedBy = "companyInfo")
    	private Collection userInfos = new ArrayList();
    }
    
    

    2. UserInfo

    
    @Entity
    public class UserInfo {
    	@Id
    	@GeneratedValue
    	private long userId;
    	private String userName;
    
    	@ManyToOne
    	@JoinColumn(name = "COMPANY_ID")
    	private CompanyInfo companyInfo;        
    
    	@ManyToMany
    	@JoinTable(name = "USER_ROLES", 
    			joinColumns = @JoinColumn(name = "USER_ID"), 
    			inverseJoinColumns = @JoinColumn(name = "ROLE_ID")
    	)
    	private Collection roles = new ArrayList();
    }
    
    

    3. Roles

    
    @Entity
    public class Roles {
    	@Id
    	@GeneratedValue
    	private long roleId;
    
    	private String roleName;
            
    	@ManyToMany(mappedBy = "roles")
    	private UserInfo userInfo;
    	
    	private List userInfos = new ArrayList();
    }
    
    

    and created the repositories for the above three entities now I want to query using hibernate relations like

    In CompanyInfoRepository

    1. I have userId and I want get the user companyInfo. we can get using two ways, one is from UserInfoRepository table which is straight forward and the other is from companyInfo table. Now the problem is I tried to query from CompanyInfoRepository but didn't succeeded.

    
    @query("select c from CompanyInfo c where :userId IN c.userInfo.id ")
    List findByUserId(@param("userId") long userId);
    
    

    I kept :userID for the argument and I used "IN" because in companyInfo UserInfos is a list

    In UserInfoRepository

    similary I have roleId and I want query it from UserInfoRepository(relation between UserInfo and Roles is ManyToMany) and here also I am getting error , I have userId and want to query from Roles table

    • Petri Feb 11, 2014 @ 21:28

      Hi Varun,

      Have you tried using inner join instead of the IN expression? Here is an example JPQL query which uses inner join (you can use the same approach for getting the users which have a specific role):

      
      @query("SELECT DISTINCT c from CompanyInfo c INNER JOIN c.userInfos u where u.id=:userId")
      List findByUserId(@param("userId") long userId);
      
      
  • Nikhil Bhalwankar Feb 17, 2014 @ 10:37

    Hi Petri,

    First of all, thanks a lot for such a nice tutorial. I am learning JPA and your tutorials are really helpful. As a matter of study, I have tried creating a maven project using the example you have given above through eclipse and then added JPA and JSF facets to the project. The necessary jar files are in place. My problem is whenever I call inbuilt methods findOne(), findAll(), save() etc of the JPARepository, It throws Null Pointer Exception. I am stuck up at this point.

    I have uploaded my project files on dropbox public folder and sharing the same here. Kindly help me on this.

    Entity:- Person.java
    https://dl.dropboxusercontent.com/u/16250517/JPA%20Project/Person.java

    Repository:- PersonRepository.java (This extends JPARepository)
    https://dl.dropboxusercontent.com/u/16250517/JPA%20Project/PersonRepository.java

    Service:- PersonService.java
    https://dl.dropboxusercontent.com/u/16250517/JPA%20Project/PersonService.java

    Service Implementation:- RepositoryPersonService.java
    https://dl.dropboxusercontent.com/u/16250517/JPA%20Project/RepositoryPersonService.java

    Transfer Object:- PersonDTO.java
    https://dl.dropboxusercontent.com/u/16250517/JPA%20Project/PersonDTO.java

    UI:- PersonController.java
    https://dl.dropboxusercontent.com/u/16250517/JPA%20Project/PersonController.java

    Webpage:- index.xhtml
    https://dl.dropboxusercontent.com/u/16250517/JPA%20Project/index.xhtml

    Also attached pom.xml, persistence.xml, applicationContext.xml, faces-config.xml and web.xml for reference.
    https://dl.dropboxusercontent.com/u/16250517/JPA%20Project/pom.xml
    https://dl.dropboxusercontent.com/u/16250517/JPA%20Project/applicationContext.xml
    https://dl.dropboxusercontent.com/u/16250517/JPA%20Project/faces-config.xml
    https://dl.dropboxusercontent.com/u/16250517/JPA%20Project/web.xml
    https://dl.dropboxusercontent.com/u/16250517/JPA%20Project/persistence.xml

    Thanks in Advance,
    Nikhil

    • Petri Feb 17, 2014 @ 20:09

      Hi Nikhil,

      Thank you for your kind words. I really appreciate them.

      I have never used JSF so I have no idea how you can use Spring beans in an application which uses JSF. However, I did find this blog post which describes how you can use Spring in web applications that use JSF 2. Maybe it will help you to solve your problem.

      • Nikhil Bhalwankar Feb 20, 2014 @ 15:34

        Hi Petri,

        Thanks for the link. I will go through the same. Meanwhile, I tried to find the mistake from my side and it looks like the repository is not getting initialized. So, it looks like the methods are not throwing NullPointer but the repository is. Is there any way to check whether repository is initialized or not? Please let me know.

        Thanks in Advance,
        Nikhil

  • Akalanka Feb 20, 2014 @ 12:45

    Hi Petri,

    I am totally new to spring mvc. Currently i am working with struts 2, spring and hibernate with Model driven. I see too many classes here to do CRUD operations. The way i use i have one struts layer class and one service layer class and the domain object class(Entity) and the DAO class. I feel like some kind of messy here. Please don't misunderstand me. I just need to learn the technology with a good design pattern. :)

  • Dean Mar 5, 2014 @ 2:22

    I'm trying to run your application with Postgres however it fails with the following stacktrace:

    Caused by:
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactoryBean' defined in class net.petrikainulaine
    n.spring.datajpa.config.ApplicationContext: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreExc
    eption: Factory method [public org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean net.petrikainulainen.spring.datajpa.config.Applicati
    onContext.entityManagerFactoryBean() throws java.lang.ClassNotFoundException] threw exception; nested exception is java.lang.IllegalStateException: re
    quired key [hibernate.hbm2ddl.auto] not found

    • Petri Mar 6, 2014 @ 22:24

      Did you make any changes to the example application? The reason why I am asking this is that the error message suggests that the property hibernate.hbm2ddl.auto was not found.

      This property is found from the application.properties file and the PersistenceContext class sets the Hibernate properties to the LocalContainerEntityManagerFactoryBean.

      If you didn't change anything, let me know so that I can investigate this issue.

      Also, thank you for asking this question. It helped me to notice that this wasn't mentioned in the first part of my Spring Data JPA tutorial. I think that I will have to update that blog post next week.

  • Jim Mar 13, 2014 @ 23:30

    Hi Petri:

    Your blog is amazing .. honestly. Your examples are very pertinent and useful - thanks!

    I have a question about this example. I'm also going to pull down your github example on this and test out your code with this scenario.

    You use 'version' and the annotation, but you don't set the version in your DTO and you don't set it in your Builder classes. Why? Doesn't this mean that version (i.e. optimistic locking) is therefore being ignored?

    In my application, if I use findOne and do not detach I am able to save Entities that 'violate' the version property (i.e. second version overwrites first). If I use findOne and then detach and update, I get the update.... OR if I create a brand new Entity and set the ID in (if it existed) and then save I also get the Optimistic Locking Exception.

    So I'm curious why you don't have a version property in your DTO and how your example would work with optimistic locking otherwise?

    I've also read your book and in your chapter on this you do not manage Version there either.

    Thanks!!
    Jim

    • Petri Mar 14, 2014 @ 0:26

      Hi Jim,

      Thank you for your kind words. I really appreciate them!

      About your question: The optimistic locking isn't handled properly in this blog post (or in my book) because handling it isn't really a Spring Data JPA specific issue. Another reason why I decided to not handle it was that it keeps the code a bit cleaner. Now that I think about this, I should have probably mentioned this in the book. :(

      Like you said, the ideal way to handle this is to put the version field to the DTO and check its value in the service method before updating the information of the entity. If you use this approach, you can decide how you should handle this. You can either overwrite the information or ask user to decide what to do.

      Also, like you suspected, the optimistic locking is ignored if other transactions haven't changed the data when the current transaction is committed (this is the typical case). If other transactions have modified the data when the current transaction is committed, an OptimisticLockException is thrown and the current transaction is rolled back (this is a rare situation but it can happen).

      • Jim Mar 17, 2014 @ 18:44

        Thanks for the confirmation Petri.

        Makes perfect sense to me, it's funny that most examples use the @Version but I haven't really seen 1 example that discusses the implications of this if you are going to use a DTO based approach, maybe b/c most examples assume the entity will be surfaced at all tiers.

        Which brings me to another question I wonder if you know the answer to. The key to the above approach working is either detaching the object PRIOR to copying any edits from the DTO class OR creating a new entity (detached) and then setting the primary key id into it .. which essentially is the same result (i.e. the JPA figures out what the row is and updates it accordingly).

        What I don't understand is WHY the entity needs to be detached for the updates to work? I would have thought the end result was the same, but I'm obviously missing something.

        Any insight appreciated. Thanks again!
        Jim

      • Sayem Ahmed Oct 22, 2014 @ 6:12

        Hi Petri,

        Regarding optimistic locking, what will happen if I just put the Version annotation in my entity and do not check for its value in the service layer? Should it throw an OptimisticLockException automatically?
        Also I was wondering about the locking mechanism implemented by JPA providers and the locking mechanism provided by the databases (i.e., in MySQL the "lock tables ..." command). Does the optimistic locking need any table locking permission for the underlying database?

        • Petri Oct 22, 2014 @ 20:34

          Hi Sayem,

          Regarding optimistic locking, what will happen if I just put the Version annotation in my entity and do not check for its value in the service layer? Should it throw an OptimisticLockException automatically?

          Yes. The Javadoc of the OptimisticLockException class states that:

          "Thrown by the persistence provider when an optimistic locking conflict occurs. This exception may be thrown as part of an API call, a flush or at commit time. The current transaction, if one is active, will be marked for rollback."

          Also I was wondering about the locking mechanism implemented by JPA providers and the locking mechanism provided by the databases (i.e., in MySQL the “lock tables …” command). Does the optimistic locking need any table locking permission for the underlying database?

          Vlad Mihalcea has written three great blog posts that answer to your question better than I ever could. These blog posts are:

  • gowtham Mar 22, 2014 @ 16:56

    Hi Petri,
    An awesome work, thanks for it and am using spring-data-dynamodb and I used annotation based confuguration and for validation is it possible to configure through annotation at present. Am struggling in that phase because am entirely new to spring environment. If its possible please guide me with a good link/sample to go through in it.

  • Ron C Apr 1, 2014 @ 17:26

    Overall like the article but I think tests should be the first step not the last step. Write a failing test that does what you expect users to do then build the bare minimum you need to pass it, rinse and repeat. It will help stop things such as scope creep and adding in code that is not needed.

    • Petri Apr 1, 2014 @ 17:52

      I agree that TDD is very useful design tool but I am not sure if the test first approach works very well in tutorials (unless you are writing a TDD tutorial). However, I think that I might use this approach when I write my testing book.

  • Ravi Apr 22, 2014 @ 14:59

    Thank you for your tutorial and codes. I find it very useful as I feel my way around JPA for my project.

    I have one question.

    My understanding is that,

    methods like create, delete in PersonService (implemented by RepositoryPersonService) use a PersonRepository instance to save to the database using the JpaRepository commands (save and delete)

    However, the update method only calls person.update. The value of the instance will be updated, but am i right i saying that the changes wont be written to the database?

    • Petri Apr 22, 2014 @ 21:16

      The reason why you don't have to call the save() method when you are updating the information of a Person object is that the object is in managed / persisted state, and the changes made to this object are automatically saved to the database when the transaction is committed.

      If you want to get more information about this, you should read the Chapter 3. Persistence Contexts of the Hibernate reference manual.

      • Ravi Apr 23, 2014 @ 8:18

        Thank you for your prompt reply. You explanation helped.

  • Nikhil Agrawal May 1, 2014 @ 17:56

    Hi Petri,
    The your tutorial seem to be very helpful for me as I am new to learn Spring Data JPA.
    Please with me so that I can do well.
    All the Best and thans for precious guidance.

    Nikhil Agrawal

  • Boris Jul 9, 2014 @ 20:24

    I got lost, how to config DB connection? Which file do I need? Which driver?

    • Petri Jul 9, 2014 @ 20:37

      The first part of this tutorial describes how you can configure Spring Data JPA. Remember that you can get rid off the XML configuration by using the @EnableJpaRepositories annotation (this tutorial was published before it was possible to use that annotation).

      • Gaurav Dighe Jul 11, 2014 @ 8:57

        I have fair knowledge on Spring -DI and Hibernate with JPA. I need to know, who create entity bean/object. Is it repository or service?
        I just tried calling ${person.name} in my JSP page. It worked. therefore, I have this question.

        • Petri Jul 11, 2014 @ 9:52

          I need to know, who create entity bean/object. Is it repository or service?

          There are two answers to this question:

          • When the example application creates a new entity object, the object is created by the service class but it becomes persistent / managed when the save() method of the PersonRepository interface is invoked.
          • When the example application finds an entity object from the database, Hibernate fetches the requested information from the database, creates a new entity object, and populates its properties by using the information found from the database.

          The following articles will shed more light to the entity life cycle:

  • Francois Jul 11, 2014 @ 12:31

    Hi Petri,

    I really appreciate your blog and those are great tutorials.
    I'm facing the following in my current project:

    I have 2 entities Process and SubProcess. Those are split for a reason and cannot be merged. Although I want to display them in one single paged grid on the ui.

    I was thinking to create a repository that would extend both repositories I already have for the process and subProcess. (So infine create a superRepo). My question is the following: would the find All(Pageable) of that superRepo get the findAll of both extended repositories?
    If not what would be the direction I should go?

    thanks in advance

    • Petri Jul 11, 2014 @ 19:41

      To be honest, I don't know the answer to your question.

      Could you tell a bit more about the relationship of the Process and SubProcess classes? If they are totally "separate" entities, it is hard to see how the super repository could work because it should support two entities and afaik this is not possible (without using inheritance).

      • Francois Jul 14, 2014 @ 10:11

        Hello Petri,

        Thanks for your prompt answer. Yes they are completely separate entites. I guess I'll solve this with displaying 2 grids instead of one. Out of curiosity I'd be interested on how you would imagine solving it with inheritance, because at the moment I don't see how.

        Thanks in advance

        • Petri Jul 14, 2014 @ 10:59

          Out of curiosity I’d be interested on how you would imagine solving it with inheritance, because at the moment I don’t see how.

          I cannot see it either. I just wondered if the SubProcess extends the Process class.

          The reason I mentioned inheritance was that you can actually create a repository for a super class and obtain all sub class objects (regardless of their type) by using its findAll() method.

          If I would have to solve this problem, I would probably follow these steps:

          1. Create a DTO which contains the information shown in a single row.
          2. Add a custom method to my repository and fetch the information of all rows. This method can return either a List<DTO> or Page<DTO> object (if you need pagination meta data, return Page object). I would probably implement this method by using JDBC because Spring Data JPA doesn't have a very good support for querying DTOs (it is possible but the support is a bit awkward).
          3. Show the results on the user interface.

          Do you think that this could work?

          • Francois Jul 21, 2014 @ 16:51

            Hello,

            Thanks for your answer, yes this seems to work, and yes the spring data queriying of a DTO is ackward. Now I just need to convince my TA that this is the solution :)

          • Petri Jul 21, 2014 @ 18:35

            Hi Francois,

            Does TA mean technical architect?

            Anyway, you can probably convince this person by arguing that this is the most efficient (in terms of performance) and the cleanest way to do this.

            My second point is of course a matter of opinion, but if you need to show everything in the same table, it is hard to figure out another solution which would be cleaner than this solution.

  • Boris Jul 13, 2014 @ 19:54

    I got
    Description Resource Path Location Type
    The import org.apache.commons.lang cannot be resolved Person.java /data-jpa-tutorial-part-one/src/main/java line 3 Java Problem.
    Can't download it by maven. Temporary I download it from the site not I am looking more clean way.
    What's wrong here?

  • Boris Jul 13, 2014 @ 20:11

    The same problem
    Description Resource Path Location Type
    The import org.hibernate.validator.constraints.NotEmpty cannot be resolved PersonDTO.java /data-jpa-tutorial-part-one/src/main/java line 2 Java Problem

    • Petri Jul 13, 2014 @ 20:20

      You need to add hibernate-validator to your pom.xml file. The example application uses version 4.2.0.Final. See its pom.xml file for more details about this.

  • Boris Jul 17, 2014 @ 15:11

    Hi Perti,
    Thanks it works, there is one more question how can I use it with spring version 4.
    Just update pom.xml? How?

    • Petri Jul 17, 2014 @ 17:27

      Well,

      you should probably update all dependency versions since some of them are very old (Spring and Spring Data JPA to mention a few).

      If you are working on a greenfield project, I recommend that you take a look at the Spring IO platform. Its goal is to make dependency management easier for developers by providing a POM file which contains the dependency versions which are known to work.

      If you want get more information about the Spring IO Platform, you should read its reference manual.

  • Boris Jul 17, 2014 @ 17:16

    It works thanks, In additional I like to use spring 4.xx with jdk 7 not 8.0 which changes requires?

    • Petri Jul 17, 2014 @ 17:33

      The configuration of the Maven compiler plugin sets the "version" of the source code and the "version" of the byte code. You should change this version from '1.6' to '1.7.' (search for the source and target elements).

      • Boris Jul 19, 2014 @ 23:09

        Thanks again, In additional I miss how JpaRepository interface knows on which DB connec
        useful, I mean "who" realize something like repository.setConnection(mycon) or repository.setEntitymanager() ,and how can I do it dynamically (similar to JDBC style)?

        • Boris Jul 19, 2014 @ 23:21

          I mean entityManager.set(myJPARepository) where myRepository is my own class impements
          JPARepository or custom interface which extends a standard Spring interface.

          • Petri Jul 20, 2014 @ 11:21

            The first part of this tutorial describes how you can configure Spring Data JPA. It is a bit outdated (it configures Spring Data JPA by using XML configuration instead of using the @EnableJpaRepositories annotation), but it should still provide some answers to your questions.

            The beans which are relevant to your question are:

            • The DataSource bean configures the used database connection.
            • The LocalContainerEntityManagerFactoryBean is responsible of creating new EntityManager objects. The method which configures this bean is responsible of configuring the used JPA provider (in this case Hibernate).

            Spring Data JPA finds your repositories by scanning the configured base package (and its child packages). You can set this base package by using either the base-package attribute of the repositories element or the basePackages attribute of the @EnableJpaRepositories annotation.

          • Boris Jul 20, 2014 @ 18:15

            But how application knows that is entityManagerFactoryBean which time is really occurs?
            On server start-up?
            In other words I have to implement on method with any name which return LocalContainerEntityManagerFactoryBean? Don't I? And what about public JpaTransactionManager transactionManager() throws ClassNotFoundException {} which part of application run it . And last, who responsible to open/close JDBC connection?

          • Petri Jul 20, 2014 @ 21:51

            But how application knows that is entityManagerFactoryBean which time is really occurs?

            Well, actually the application doesn't know about it. The Spring container injects a proxy implementation of the repository interface to all beans which use it.

            On server start-up?

            This happens when the Spring IoC container is started. If your application is a web application, this happens when on server start-up. If you are not familiar with the Spring IoC container, you should read the Chapter 4 of the Spring Reference Manual.

            In other words I have to implement on method with any name which return LocalContainerEntityManagerFactoryBean? Don’t I?

            If you want to use JPA, you have to create this bean. Read the section 14.5 of the Spring Reference Manual for more details about this.

            And what about public JpaTransactionManager transactionManager() throws ClassNotFoundException {} which part of application run it .

            That method configures that transaction manager bean. If you use JPA, you should use the JpaTransactionManager as a transaction manager bean.

            You can get more information about transaction management by reading the chapter 11 of the Spring Reference Manual.

            And last, who responsible to open/close JDBC connection?

            You can request a new connection from the DataSource bean, but you don't have to do it yourself. If you use Hibernate as a JPA provider, it will take care of this.

  • Deepak Jain Aug 27, 2014 @ 16:21

    I have a Entity class Trade.java which uses a composite key TradeKey.java. I am using @EmbeddedId annotation.
    TradeKey has two attributes tradeId and companyNumber.
    I have written a ITradeRepository which extends CrudRepository.
    I want to select all trades based on companyNumber. How to write find method in ITradeRepository?

    • Petri Aug 28, 2014 @ 18:22

      You could try something like this:

      
      @Query("SELECT t FROM Trade t WHERE t.key.companyNumber=:companyNumber")
      public List<Trade> findByCompanyNumber(@Param("companyNumber") Integer companyNumber);
      
      

      Note that the key is the name of the composite key property that is found from the Trade class.

  • Sandeep Sep 11, 2014 @ 23:34

    Hi,
    Great tutorial! Can you help with this bcoz Im using Spring Data JPA, I thought you could help on this : http://stackoverflow.com/questions/25771892/column-insertable-updateble-dont-go-well-with-spring-jpa

    • Petri Sep 14, 2014 @ 21:20

      Hi,

      When you are creating a new Offer object, do you get the Channel object from the database or simply just create a new Channel object?

      If you aren't fetching the Channel object from the database, Hibernate probably performs insert to the channel table when you save a new offer because the Channel object is not in the managed state.

      Unfortunately the code that you added to your StackOverflow question didn't reveal how the Channel object is created. If you can shed some light to this issue, I can probably give you a better answer.

  • marco Oct 16, 2014 @ 21:14

    Hi,

    very intresting and clear tutorial. I have a couple of question left before to start evolving an old project to Spring.

    1. You mentioned you would use VOs instead of the 'monolitich' DTO in case of more complex entities, I suppose this is valid also in case of collection fields (@OneToMany relations). Will you in that case include in VO/DTO collection of Domain Entity (as in the Domain entity itself) or collections of reduced DTO/VTO tailored to the needs of the client? Where Will you put the logic to assemble/dissassemble Domain Objects in DTO/VO? Specific servers or into the Domain Object itself?. How will you handle transactions when different entities are involved? bit confused...

    2. In your example, Person is the Domain Entity AND the Persistence Object, DTO/VO are involved only from domain to UI and viceversa. Is this the common/best practice with spring? You don't want to separate the data layer, just in case you need to move from a RDMS to a NoSQL DB or...

    3. For some Domain Object I actualy retrive some data from the database AND some other from somewere else (today is the filesystem, but I'm late to provide access to a legacy filesharing application, and It's easy precognize the needs for clouds based or web services). How will you handle this without create new artificial domain entities? Now I've a method directly in the Entity class, but as you could understand, this is on e of the majr concerne that move me to reengineer the application.

    Quite articulate question, sorry about that.

    Marco

    • Petri Oct 18, 2014 @ 11:40

      Thank you for you kind words. I really appreciate them. Also, thank you for writing such an awesome question!

      You mentioned you would use VOs instead of the ‘monolitich’ DTO in case of more complex entities, I suppose this is valid also in case of collection fields (@OneToMany relations). Will you in that case include in VO/DTO collection of Domain Entity (as in the Domain entity itself) or collections of reduced DTO/VTO tailored to the needs of the client?

      I only fetch and return the information that is needed by the client (in case of REST API) or the view. Even though I call these objects DTOs, I guess you call them view objects as well.

      I might reuse the same DTO if two two views need exactly the same information or two REST API endpoints return exactly the same information.

      If I need to return an object that contains a collection of objects, I will create a separate DTO that contains the information of the objects found from that collection. In other words, I will create a DTO that has a collection of DTOs.

      I never return domain model objects (entities or value objects). However, the example application of this tutorial uses a different approach because it was written a few years ago. Nowadays I use the approach which I described here.

      Where Will you put the logic to assemble/dissassemble Domain Objects in DTO/VO? Specific servers or into the Domain Object itself?.

      If I am inside a read-write transaction, I put the logic to a special mapper classes and use these classes in my service layer. I might also use a library such as jTransfo, Dozer, and ModelMapper.

      If I am inside a read-only transaction, I query DTOs directly from the database. This way I can get only the information I need and avoid the overhead of Hibernate (or any other JPA provider). In this case, I put the logic that converts query results into DTOs to my repository class. Typically I use the JdbcTemplate and the BeanPropertyRowMapper classes for this purpose.

      How will you handle transactions when different entities are involved? bit confused…

      Spring Framework has a comprehensive support for transactions. I use the annotation driven transaction management, and add the @Transactional annotation to my service methods.

      In your example, Person is the Domain Entity AND the Persistence Object, DTO/VO are involved only from domain to UI and viceversa. Is this the common/best practice with spring? You don’t want to separate the data layer, just in case you need to move from a RDMS to a NoSQL DB or…

      I want to avoid complexity when it is not absolutely necessary. In other words, if the requirements of the application don't state that the application must support both relational databases and NoSQL databases, I won't take this possibility into account when I design and implement the application.

      The truth is that no one cannot know what happens in the future. This means that there are many variables that can change, and if we want to support all of them, we need to over engineer everything. Over engineering has two big problems:

      • Writing new features is slow because we need to pass the information through too many layers.
      • Maintaining our software is a huge pain in the ass because no one cannot understand how our application really works.

      This is of course a tradeoff, but I have noticed that doing the simplest thing that works is often the best choice.

      For some Domain Object I actualy retrive some data from the database AND some other from somewere else (today is the filesystem, but I’m late to provide access to a legacy filesharing application, and It’s easy precognize the needs for clouds based or web services). How will you handle this without create new artificial domain entities? Now I’ve a method directly in the Entity class, but as you could understand, this is on e of the majr concerne that move me to reengineer the application.

      I would create a new domain object that has references to the entity (or entities) in question and to the information that you fetch from the file sharing application. This gives you the possiblity to keep that information together, and you can also add relevant business logic to that domain object. On the other hand, if you only need to provide that information to the user's of your application and you don't need any business logic, adding a transient field to the entity is probably fine as well.

      • Anonymous Oct 18, 2014 @ 17:24

        Hi, great answers and I'll need some time to elaborate them.

        I understand your point about avoiding complexity and it was what I did at the beginning, using Swing application famework with netbeams. It was usefull and now at least I know very well the 'domain' of the application, but is time to evolve, and my concern are:

        a. provide a better integration and distribution respect as today.
        b. enable web and mobile clients for all or at least part of the application domain.
        c. move from swing to other (and more modern and rich) 'rich' GUI container (if one is still needed).
        d. be ready to move from mySQL + MS/SAMBA directory sharing to other DBMS and fileservers/clouds application.

        Your advise will be greatly appreciated on every point, but strictly to the point of this blog d. only is involved. Your answer state You don't want take care of what is not a requirement at the moment, but what if it is? Would you still handle it with spring?

        I've read the spring tutorial and I'm aware is possible to have different datasouces at the same time for differents entitities, but in that tutorial persistence.model.entity and domain.model.entity are two separated class and this pattern will for sure lend to many heavy extracost (i.e you are going to always deal with detached entities and updates must be atomics, a real nightmare with collection fields), I'm not aware of tools who could help you using this pattern, but maybe you are.

        What is not clear to me and urged me to my first question to you is: is this a required pattern with Spring using different datasources?

        If not, is it the best/common practice?

        Why not use the same Entity Class instead (as you did) eventually implementing different interfaces for different needs (i.e one interface is 'anhemic' and rapresent the entity in the data layer, onother is rich and rapresent the entity in the domain layer) in order to ensure 'logical' separation?

        Of course when heavy security (?) or performance constraints apply, then you have no choice.

        Probably I'm wrong, but I'm interested in your opinion.

        Regards, Marco.

        • marco Oct 19, 2014 @ 0:03

          Don't know why I posted as anonimus... sorry about that.

        • Petri Oct 19, 2014 @ 11:36

          Thank you for writing another great question.

          It seems that you might want to take a look at the following Spring projects:

          Your answer state You don’t want take care of what is not a requirement at the moment, but what if it is? Would you still handle it with spring?

          Well, Spring does provide a good support for relational databases and NoSQL databases. The first thing that you should do is to find the answer to the following questions:

          • Do you need to store all information either to a relational database or to a NoSQL database?
          • Do you want to use polyglot persistence? In other words, do you want to store some information to a relational database and some information to a NoSQL database?

          If you want to store all information either to a relational database or to a NoSQL database, there is no framework that can save you from the additional complexity. This means that you have to create a domain model and encapsulate the database specific details into your repositories. Spring can help you to implement these repositories because the Spring Data project provides a first class support for both relational and NoSQL databases.

          If you want to store information to a relational database and some information to a NoSQL database, Spring can make your job a lot easier because it you can eliminate the boilerplate code by using Spring Data.

          I’ve read the spring tutorial and I’m aware is possible to have different datasouces at the same time for differents entitities,but in that tutorial persistence.model.entity and domain.model.entity are two separated class and this pattern will for sure lend to many heavy extracost (i.e you are going to always deal with detached entities and updates must be atomics, a real nightmare with collection fields), I’m not aware of tools who could help you using this pattern, but maybe you are.

          Are you talking about a specific tutorial? It would be easier to answer to this question if you would identify the tutorial you are talking about.

          What is not clear to me and urged me to my first question to you is: is this a required pattern with Spring using different datasources?

          Well, if you want to use Spring Data JPA and some other Spring Data project, you have to create a domain model that is supported by both projects. This can tie your hands because

          1. Relational databases and NoSQL databases are totally different beasts. NoSQL databases don't support all features of the relational databases (and vice versa).
          2. You have to configure the way your entities and value objects are stored to the used database. JPA provides a far richer set of configuration options than the NoSQL specific Spring Data projects.

          That is why it is a better idea to encapsulate the persistence specific details into your repositories and use a common domain model that isn't database specific.

          If not, is it the best/common practice?

          This is the simplest thing than could possibly work. Using the same entities might seem like a simple idea, but you might run into problems when you need to support relationships between different entities and the other stuff supported by JPA. If you want to use JDBC or a "native" NoSQL database client library, you can probably dodge this bullet, but this means that you have to add a lot of boilerplate code to your repositories.

          Why not use the same Entity Class instead (as you did) eventually implementing different interfaces for different needs (i.e one interface is ‘anhemic’ and rapresent the entity in the data layer, onother is rich and rapresent the entity in the domain layer) in order to ensure ‘logical’ separation?

          See my previous answers.

          Again, if you think that I missed something or you have some additional questions, feel free to ask them!

          • marco Oct 19, 2014 @ 23:42

            Hi, thanks again for your precious help.

            This is the tutorial: http://spring.io/guides/tutorials/data/

            I understand your answer and I think I'm in an intermediate situation:

            1.The 'core' is based on one RDB an I could not see the need of more (filesystem apart, as we already discussed. I'm cosidering to move the filesystem integration to the service layer (as you suggested), that way the 'core' (and any module) will interact with only one persistence subsystem).

            2. Other part of the system (say modules) are served by web services and they are loosely coupled by design.

            3. It could be possible in the near future to replace the filesystem and/or web service access with one or more additional database access, this could introduce the need of one more persistence subsystem, but not necessarly will lend to a tighter integration between modules.

            In this situation, and accepting the risk that could arise if needs will change in future, I could not see any caveat in adopting your way, even if in the whole system more than one persistence subsystem is used, but probably I'm missing the point.

            Any way, if I'll have to go the other way, as you wrote I'll have to write a lot of boilerplate and code just to map the domain objects to the entities. Then arise my question about how to handle updates, particolary in case of entities with collection fields (relations). I was not able to find any Spring tutorial on that matter, are you aware of any example or tutorial about this?

            p.s.
            I'll be very happy to owe you a beer, but considering you gave me seven more project/library to study... I think I'm not going to earn much money in the next couple of months :).

            Marco.

          • Petri Oct 20, 2014 @ 22:26

            Hi Marco,

            you are welcome. And thank you for coming back and asking more questions (these questions help me to learn new things).

            This is the tutorial: http://spring.io/guides/tutorials/data/

            I took a quick look at it and it seems that this tutorial separates the "core domain" and the "persistence data model" because the application needs to support multiple different databases / data storages. I wouldn't use this approach unless it is absolutely necessary because most of the time this adds unnecessary complexity to the application.

            I understand your answer and I think I’m in an intermediate situation:

            Often the best solution is to find a some kind of compromise between flexibility and simplicity. The thing is that there is no perfect solution that would be suitable for every situation.

            If you decide that you need to be able switch from a relational database to a NoSQL database (and vice versa) without making any changes to the source code, you have to write more code before you can "release" your application.

            On the other hand, if you want to write less code before you can "release" your application, you cannot switch from a relational database to a NoSQL database (and vice versa) without making changes to the source code.

            However, you can identify the modules that have to support multiple different databases, and add this support only to these modules. I know that this isn't a perfect solution but it can be a good compromise.

            Any way, if I’ll have to go the other way, as you wrote I’ll have to write a lot of boilerplate and code just to map the domain objects to the entities. Then arise my question about how to handle updates, particolary in case of entities with collection fields (relations). I was not able to find any Spring tutorial on that matter, are you aware of any example or tutorial about this?

            I wrote a very similar update function today at work. I can share it here but I have to "anonymize" it first. I think that I can do that tomorrow. I will send you an email after I have published it.

            ’ll be very happy to owe you a beer, but considering you gave me seven more project/library to study… I think I’m not going to earn much money in the next couple of months :).

            But you won't spend any money either because you will spend the next couple of months at home studying these libraries... ;)

            By the way, you might want to read my latest blog post titled: Understanding Spring Web Application Architecture: The Classic Way.

          • marco Oct 21, 2014 @ 14:04

            Hi,

            I'm looking forward for your update function, and I'll read for sure your blog, write the web app will be next step.

            Marco

          • Petri Oct 21, 2014 @ 20:45

            Hi Marco,

            My use case is very simple but essentially I have two entities: Task and Tag. Their source code looks as follows:

            
            @Entity
            @Table(name = "tasks")
            public class Task {
            
                @Id
                @GeneratedValue(strategy = GenerationType.AUTO)
                private Long id;
            	
                @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
                @JoinTable(name = "task_tags",
                        joinColumns = @JoinColumn(name = "task_id", nullable = false),
                        inverseJoinColumns = @JoinColumn(name = "tag_id", nullable = false)
                )
                private Set<Tag> tags = new HashSet<>();
            }
            
            @Entity
            @Table(name = "tags")
            public class Tag {
                
            	@Id
                @GeneratedValue(strategy = GenerationType.AUTO)
                private Long id;
            	
            	@Column(name = "name", nullable=false)
            	private String name;
            }
            
            

            Now, I had to write an update method that updates every Tag object that is linked with a Task object. Also, I could assume that existing tags are not removed and new tags are not added. The source code of my update method looks as follows:

            
            @Service
            public class TaskUpdateService {
            
            	private final TaskRepository repository;
            	
            	@Autowired
            	public TaskUpdateService(TaskRepository repository) {
            		this.repository = repository;
            	}
            
            	@Transactional
            	public TaskDTO update(TaskDTO task) {
            		//No null check because it doesn't matter in this example
            		Task updated = repository.findOne(task.getId());
            	
            		updateTags(updated.getTags(), task.getTags())
            		
            		//Create a new TaskDTO object from the updated Task object and return it
            		TaskDTO returned = ...
            	}
            	
            	/**
            	 * Updates all tags. This method assumes that existing tags 
            	 * cannot be removed and new tags cannot be added. 
            	 * Also, this method makes sense only if the number of
            	 * tags is relatively small.
            	 */
            	private updateTags(Set<Tag> targetTags, Set<TagDTO> sourceTags) {
            		for (Tag targetTag: targetTags) {
            			TagDTO sourceTag = findSourceTag(targetTag.getId(), sourceTags);
            			targetTag.setName(sourceTag.getName());
            			sourceTags.remove(sourceTag);
            		}
            	}
            	
            	private TagDTO findSourceTag(Long tagId, Set<TagDTO> sourceTags) {
            		Optional<TagDTO> sourceTag = sourceTags.stream()
            		                .filter(t -> t.getId().equals(tagId))
            		                .findFirst();
            		return sourceTag.orElseThrow(() -> new NotFoundException());
            	}
            }
            
            

            Any feedback?

          • marco Oct 22, 2014 @ 14:26

            HI, tanks for the example, for the matter of updating the collection field is similar to the one I was thinking of (but I need also add and remove methods, so I'm actualy thinking on a 'sub service' to handle the inner collection, with findRemoved, remove, findAdded, add, find and update methods). If interested in it, I could post an early version as soon as I'll have sketched, but I think you got the idea.

            My real concern is: what if you have other fields and maybe other collections in Task? Will you then have differerent 'atomic' TaskUpdateService for each field? Same for Tags and any other entity.

            Using non atomic updates (on detached entities) could land you in big troubles of 'logical' concurrency, depending on the number of users and lasting life of DTO's.I don't think @Transactional is going to help us in this matter.

            From a genaral point of view, I don't like the idea to have this kind of stuff in the service layer (no business logic here, it's just a different implementation of the data access layer than using an ORM), maybe - if we really need it - we are better introducing a layer of abstraction between repositories and the service layer, so Service layer will not change if we change kind and number of datasources or repo implementation.

            Marco.

          • Petri Oct 22, 2014 @ 21:59

            for the matter of updating the collection field is similar to the one I was thinking of (but I need also add and remove methods, so I’m actualy thinking on a ‘sub service’ to handle the inner collection, with findRemoved, remove, findAdded, add, find and update methods). If interested in it, I could post an early version as soon as I’ll have sketched, but I think you got the idea.

            I would just add the addTag() and removeTag() methods to the service class, and then delegate the request forward to the Task object since it is the aggregate root (DDD Aggregate).

            My real concern is: what if you have other fields and maybe other collections in Task? Will you then have differerent ‘atomic’ TaskUpdateService for each field? Same for Tags and any other entity.

            It depends. My situation is pretty simple since I only need to update one field. If I would have to update a few fields, I would update them all at the same time. But if I would have to update a child collection of a Task object or more than just a few fields, things would get ugly.

            Using non atomic updates (on detached entities) could land you in big troubles of ‘logical’ concurrency, depending on the number of users and lasting life of DTO’s.I don’t think @Transactional is going to help us in this matter.

            That is why I would update all fields inside the same transaction.

            From a genaral point of view, I don’t like the idea to have this kind of stuff in the service layer (no business logic here, it’s just a different implementation of the data access layer than using an ORM), maybe – if we really need it – we are better introducing a layer of abstraction between repositories and the service layer, so Service layer will not change if we change kind and number of datasources or repo implementation.

            Actually I decided move this logic to the Task class. I added the updateTag(Long id, String name) method to the Task class. This method finds the updated Tag object and updates its name. Of course this works only because a Task object won't have many Tag objects and I have to update only one field.

          • Marco Oct 29, 2014 @ 20:10

            Hi, If I well understand your point, you will have the

            addTag(Task task, Long tagId, String TagName);
            removeTag(Task task, Tag tag);

            in your TaskService class that delegate to same methods in Task:

            addTag(Long tagId, String TagName);
            removeTag(Tag tag);

            assuming addTag has to first create the tag (if not exists) and removeTag delete the tag if not used anymore, where you will add this logics?

            If in Task, it will not be a DTO anymore, but a Class that incapsulate data and logics, very similar to the concept of Entity in my opinion. More, Task must know how to persist/remove Tag. This breaks the original requirement to be able to switch the way Task or Tag are persisted.

            For this reason I was thinking - if and only if we really need this capability - to introduce an intermediate level of abstraction - let's call it TaskIntermediate - between the DAO/DTO (TaskDAO, TagDAO, TaskDTO, TagDTO) and the domain object Task.

            This way Task only have addTag(Tag tag) and RemoveTag(Tag tag) abstract methods, TaskIntermediate implements the methods via call to:

            Tag tag = TagDTO.create(tagId, TagName) ;
            TagDTO.persist(tag);
            this.getTagList().add(tag);

            and so on.

            The benefit is that you could use ORM to handle DTOs and generics for CRUD operations in DAOs, concentrate the 'assembling' logics in the Intermediate Class (and an intermediate server implementing the aggregate CRUD operations onto the aggregate) and live with 'clean' and not anhemic at all domain objects and services, completely unrelated to where and how data are stored.

            Thanks to you I've cleared up my mind and now I could better articulate my original question: If TaskIntermediate is just TaskDTO + the logics to handle related Tags (the add/remove methods) and the list of tags, could TaskIntermediate extend TaskDTO via inheritance or composition? if not why?

            Same for Task vs. TaskImplementation, assuming Task adds some business related methods.

            Looking forward for your opinion.

            Marco.

          • Petri Nov 3, 2014 @ 21:09

            Hi Marco,

            If I well understand your point, you will have the

            addTag(Task task, Long tagId, String TagName);
            removeTag(Task task, Tag tag);

            in your TaskService class that delegate to same methods in Task:

            addTag(Long tagId, String TagName);
            removeTag(Tag tag);

            Yes, and no. In this case the TaskService class would have the following methods:

            
            public Tag addTag(Long taskId, String tagName);
            public Tag removeTag(Long taskId, Long tagId);
            
            

            And the Task class would have the following methods:

            
            public Tag addTag(String tagName);
            public Tag removeTag(Long tagId);
            
            

            Actually I don't have the removeTag() method because there is no way to remove tags (they aren't really tags).

            assuming addTag has to first create the tag (if not exists) and removeTag delete the tag if not used anymore, where you will add this logics?

            I would add this logic inside the Task class because of two reasons:

            1. It is an aggregate root class so it makes sense to add it there.
            2. Adding and removing tags is so simple that I don't need an additional builder component.

            If in Task, it will not be a DTO anymore, but a Class that incapsulate data and logics, very similar to the concept of Entity in my opinion.

            Yes. The Task class is an entity (at least in my application).

            More, Task must know how to persist/remove Tag. This breaks the original requirement to be able to switch the way Task or Tag are persisted.

            It doesn't have to know this as long as it returns the added / removed Tag object. When you get the returned Tag object, you can do what you want with it.

            For this reason I was thinking – if and only if we really need this capability – to introduce an intermediate level of abstraction – let’s call it TaskIntermediate – between the DAO/DTO (TaskDAO, TagDAO, TaskDTO, TagDTO) and the domain object Task.

            This way Task only have addTag(Tag tag) and RemoveTag(Tag tag) abstract methods, TaskIntermediate implements the methods via call to:

            Tag tag = TagDTO.create(tagId, TagName) ;
            TagDTO.persist(tag);
            this.getTagList().add(tag);

            and so on.

            I am not sure if I understand what you mean. I use DTOs to transform information between different layers (web -> service and service -> web), and I think that there shouldn't be any dependencies between DTOs and entities. If I need to assemble objects that requires special assembling logic, I create a domain service that creates those objects.

            On the other hand, If would have to support multiple different databases, I would probably just separate the domain model and the data model by using the approach that was described on the Spring Data tutorial (it seems that the link is not working anymore so I couldn't link to it).

            The benefit is that you could use ORM to handle DTOs and generics for CRUD operations in DAOs, concentrate the ‘assembling’ logics in the Intermediate Class (and an intermediate server implementing the aggregate CRUD operations onto the aggregate) and live with ‘clean’ and not anhemic at all domain objects and services, completely unrelated to where and how data are stored.

            I am not sure if I understand this because my DTOs aren't passed to the data access layer. Also, since I don't have to support multiple different databases, I can just use JPA entities (this means that my data model and domain model are kind of the same thing).

            Thanks to you I’ve cleared up my mind and now I could better articulate my original question: If TaskIntermediate is just TaskDTO + the logics to handle related Tags (the add/remove methods) and the list of tags, could TaskIntermediate extend TaskDTO via inheritance or composition? if not why?

            I think that I don't understand what the role of the intermediate layer is. Is it a some kind of domain service that assembles objets that require complex assemling logic? Or is it a mapper layer that separates the service layer from the repository layer?

            Same for Task vs. TaskImplementation, assuming Task adds some business related methods.

            What is the difference between Task and TaskImplementation?

  • David Dec 18, 2014 @ 22:23

    Hello Petri.

    First of all, thanks for your great posts. I'm working in an app using the architecture defined here and Spring Data JPA. I'm enjoying programming this following your advices but there is a thing that I don't understand. According to your diagram, web layer should use only DTOs and in this post you return a list of Person insteand a PersonDTO. Is there a justification for this? If not, how could I rewrite that method to return DTOs instead?

    Thanks again por your help. Great job! ;)

    • Petri Dec 19, 2014 @ 20:16

      Hi David,

      Thank you for your kind words. I really appreciate them.

      According to your diagram, web layer should use only DTOs and in this post you return a list of Person insteand a PersonDTO. Is there a justification for this?

      I assume that you are talking about the diagram that is found from this blog post?

      Anyway, the only reason why the service layer of the example application returns entities is that it was written almost three years ago, and three years ago I thought that returning entities is a good idea.

      If you want to return DTOs from your service layer, you have to simply transform the domain objects into DTO objects and return the created DTO objects from your service methods.

      If you want to see an example application that uses this approach, check out the example application of my Using jOOQ with Spring tutorial.

      Its service methods transform domain objects into DTOs by using jTransfo and return the created DTO objects. However, you don't have to use an external library. You can simple write the mapper code yourself if it makes more sense to you.

      I hope that this answered to your question.

  • Awadhesh Jan 20, 2015 @ 13:50

    Hi Perti,
    Thank you so much.Its very helpful tutorial.

    I have a requirement to connect with multiple (let's say two as of now) databases. So I am creating two repositories and using both of them in one service method.

    I am trying to fetch record from one repo and persist in second repo but getting below error -

    org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.transaction.PlatformTransactionManager] is defined: expected single matching bean but found 2:

    • Petri Jan 20, 2015 @ 15:34

      Hi,

      That exception was thrown because Spring expected to find only one PlatformTransactionManager bean but it found two PlatformTransactionManager beans. Did you configure the used transaction manager when you annotated your configuration class with the @EnableJpaRepositories annotation?

      Also, you might want to read this blog post. It describes how you can use multiple databases with Spring Data JPA.

  • BB Jan 22, 2015 @ 12:59

    Hi your site is excellent.
    Thank you for your hard work.

    Maybe you can write one some think like this - "how to use spring-data-jpa-tutorial-part-two-crud in Rest resources" I mean "how to inject/@Autowire @Repository variable in rest resource"

    • Petri Jan 22, 2015 @ 20:49

      Thank you for your kind words. I really appreciate them.

      Also, thank you for your suggestion. I think that I will add a few practical blog posts to my Spring web application architecture tutorial (read the first part of this tutorial). What do you think?

  • Ben Feb 21, 2016 @ 7:37

    Thank you very much for the wonderful articles.

    When you created the BaseRepository, you added @NoRepositoryBean, so that spring will not try to create implementation of it. And that makes sense.

    But when i see the CrudRepository Interface from the org.springframework.data.repository package, it have the @NoRepositoryBean annotation on top of the class.

    Why is this annotation needed for the crudRepository interface ? Don't we need spring to create implementation of the methods for the methods in the crudRepository interface ?

    • Petri Feb 21, 2016 @ 21:21

      Hi Ben,

      Thank you for your kind words. I really appreciate them.

      But when i see the CrudRepository Interface from the org.springframework.data.repository package, it have the @NoRepositoryBean annotation on top of the class. Why is this annotation needed for the crudRepository interface ? Don’t we need spring to create implementation of the methods for the methods in the crudRepository interface ?

      Check out the Javadoc of the @NoRepositoryBean annotation. These interfaces are annotated with that annotation because we don't want that the Spring container creates beans for those base interfaces. Instead, we want that the Spring container creates beans for our "concrete" repository interfaces.

  • john Sep 28, 2016 @ 5:22

    purpose: update some columns of same table by given list of primary keys and return ordered int[] to indicate if a row update is successful or not

    query (not native): update MyEntity e set e.col_1 = :v1, e.col_2 = :v2 where e.id in :ids

    @Modifying(clearAutomatically = true) @Transactional public int updateCols(@Param("v1") String v1, @Param("v2") String v2, @Param("ids") List idList);

    Spring JpaTransactionManager is used

    Questions: 1) With Spring Data JPA only, how to do that? (customize repository not an option due to large existing codes), we want to achieve effects equivalent to JDBC batch update with Spring data JPA only. 2) Is it possible that spring data JAP will return an integer by the update method above that is less then the input list size? If that could happen, how do we know which one on my input list failed? In any order? 3) Noticed that after the above method successfully finished, database rows not being updated at all. How could we force it synchronized with database with spring data jpa? 4) If the entity update not flushed by spring data JPA, then even we update one by one instead of in a batch, still we will not see database changes? Thanks in advance

  • Anonymous Oct 4, 2016 @ 15:59

    Not clear as article, Repository topic it's not clear enough.

    • Petri Oct 4, 2016 @ 23:48

      Could you clarify that comment? I am not sure what you mean.

  • Arun Jan 14, 2017 @ 5:40

    Hi Pettric,
    need your help regarding the below

    EntityClass{
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="ID",columnDefinition=" INT UNSIGNED")
    private Integer id;

    @Column(name="TOKEN_CODE",length=80,nullable=false,unique=true)
    private String regionId;

    @Column(name="FM_NAME",length=80)
    private String fmName;

    @OneToOne(cascade=CascadeType.ALL)
    @JoinColumn(name="COURIER_NO")
    private Courier courier;
    @OneToMany(mappedBy="admin")
    private List privilege = new ArrayList();

    I have tried two scenario 1-when using findbyid for retrieving the object and try to set the data in the object in the same field then we are getting an identity already attached with other session 2-when we commented all property setter method which has one to one then it is always creating a new entity in(admin) the table which has one to many relationship As saveorUpdate also not available in Spring Data JPA so could any suggest how we can do the cascade update in Spring Data

  • Alejandro May 18, 2017 @ 18:47

    Petri,
    The way you have written these blogs in layman's terms is so refreshing. I have learned so much so far from you spring data tutorials. keep up the great work!

    • Petri May 19, 2017 @ 18:51

      Thank you for your kind words. I really appreciate them!

  • arshil Jun 7, 2017 @ 0:11

    Is there any support of deleteby with "and" clause . e.g. : deleteByFirstNameAndLastName

    • Petri Jun 9, 2017 @ 12:40

      Hi,

      As far as I know, the query generation from the method name supports only SELECT queries. In other words, if you want to create DELETE queries, you have to either invoke the delete() method or use the @Query annotation.

  • arun singh Feb 24, 2018 @ 16:15

    big help, thanks sir

    • Petri Mar 12, 2018 @ 8:44

      You are welcome.

  • Ram Mar 28, 2018 @ 20:15

    Hi Petri
    Thank you for taking time to write blogs in addition to your book. I have used JPA in my past projects and did not get chance to use it in the past few years. I wanted to use it again on a new project and I am running in to a strange issue.

    WARN org.springframework.context.annotation.AnnotationConfigApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'TodoRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Failed to create query for method public abstract java.util.List com.repositories.BaseRepository.findAll(org.springframework.data.domain.PageRequest)! No property findAll found for type TodoEntity!

    • Petri Mar 28, 2018 @ 20:56

      Hi,

      Thank you for your kind words. I really appreciate them. About your problem, there are a couple of things you can check:

      • Ensure that you have specified the the package of the BaseRepository when you enabled Spring Data JPA (check the value of the @EnableJpaRepositories annotations' basePackages attribute).
      • Ensure that the package of the TodoEntity entity is scanned by the entity manager. You can configure this package when you create the LocalContainerEntityManagerFactoryBean bean.

      Also, if your application is based on any of my examples, you shouldn't change the Spring Data JPA version of the example. The reason for this is that the newer versions of Spring Data JPA use a bit different API which might cause compilation failures and other issues.

  • Kiran Apr 4, 2018 @ 14:09

    Hi Petri,
    Can you please create a tutorial or at-least guide me to write Java Entities on three tables that are mapped together in OneToMany. More details can be seen here (https://www.w3resource.com/sql/sql-table.php). I want to write a program that can do the CRUD operations on those three tables using Hibernate. Thank you very much in advance.

  • Braian Nov 23, 2018 @ 21:21

    Can I extend TodoRepository in another Repository and create an Implementation? I have 3 services with these common methods create(), deleteById(), findAll(), getById() and update().
    I would like to turn them into interface and create the implementation with the business logic in them.
    Would it be a good practice to create an interface with these common methods to extend then implement them? Because every time I have to be creating these methods.
    Example:
    TodoRepository with Crud methods

    AuthorService extend GenericService and has its findByName() method.
    public interface AuthorService extends TodoRepository {
    public AuthorEntity findByName(String name); }

    AuthorServiceImpl implements GenericService with the AuthorService method.
    @Service
    public class AutorServiceImpl implements AutorService {/...../}

  • Sheetal Apr 8, 2019 @ 15:05

    Hi Petri
    How would an update work in case of M-to-M relationship, using Spring Boot and JPA. For instance consider, Student has a list of Subjects, I may update only one subject of his, but that involves looping twice, which I find to be increasing unnecessary time complexity. Is there a way through which I can perform the update without costing additional overhead?

Leave a Reply