Do you want to get a better understanding of Spring web application architecture? If so, get started right now!

Spring Data JPA Tutorial Part Two: CRUD

A water drop

The first part of my Spring Data JPA tutorial described, how you configure Spring Data JPA. This blog entry goes a bit deeper and describes how you can use Spring Data JPA for creating a simple CRUD application. The requirements of the application are following:

  • The person must have a first name and last name. Both of these properties are mandatory.
  • It must be possible to list persons.
  • It must be possible to add new persons.
  • It must be possible to edit the information of existing persons.
  • It must be possible to delete persons.

I have now described the requirements of the created application. Now it is time to get to work and start implementing it.

Required Steps

The implementation of CRUD application can be divided to following steps:

  • Implementing the Person model object
  • Creating a repository for the Person object
  • Using the created repository

Each of these steps is explained with more details in following.

Implementing the Model Object

The implementation of the Person class is pretty simple. However, there are few issues which I would like to point out:

  • A builder is used to to create new instances of Person class. This might seem like over engineering but I like this approach for two reasons: First, it makes code easier to read than using the telescopic constructor pattern. Second, it ensures that you cannot create an object which in an inconsistent state during its construction (This is something that the common JavaBeans pattern cannot guarantee).
  • The only way to change the information stored in a Person object is to call the update() method. I am fan of putting as much logic to the model objects as possible. This approach does not clutter the service layer with domain logic and and ensures that you do not end up with an anemic domain model.

The source code of my Person class is given in following:

import org.apache.commons.lang.builder.ToStringBuilder;

import javax.persistence.*;

/**
 * An entity class which contains the information of a single person.
 * @author Petri Kainulainen
 */
@Entity
@Table(name = "persons")
public class Person {
    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    
    @Column(name = "creation_time", nullable = false)
    private Date creationTime;
    
    @Column(name = "first_name", nullable = false)
    private String firstName;

    @Column(name = "last_name", nullable = false)
    private String lastName;
    
    @Column(name = "modification_time", nullable = false)
    private Date modificationTime;
    
    @Version
    private long version = 0;

    public Long getId() {
        return id;
    }

    /**
     * Gets a builder which is used to create Person objects.
     * @param firstName The first name of the created user.
     * @param lastName  The last name of the created user.
     * @return  A new Builder instance.
     */
    public static Builder getBuilder(String firstName, String lastName) {
        return new Builder(firstName, lastName);
    }
    
    public Date getCreationTime() {
        return creationTime;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    /**
     * Gets the full name of the person.
     * @return  The full name of the person.
     */
    @Transient
    public String getName() {
        StringBuilder name = new StringBuilder();
        
        name.append(firstName);
        name.append(" ");
        name.append(lastName);
        
        return name.toString();
    }

    public Date getModificationTime() {
        return modificationTime;
    }

    public long getVersion() {
        return version;
    }

    public void update(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
    
    @PreUpdate
    public void preUpdate() {
        modificationTime = new Date();
    }
    
    @PrePersist
    public void prePersist() {
        Date now = new Date();
        creationTime = now;
        modificationTime = now;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

    /**
     * A Builder class used to create new Person objects.
     */
    public static class Builder {
        Person built;

        /**
         * Creates a new Builder instance.
         * @param firstName The first name of the created Person object.
         * @param lastName  The last name of the created Person object.
         */
        Builder(String firstName, String lastName) {
            built = new Person();
            built.firstName = firstName;
            built.lastName = lastName;
        }

        /**
         * Builds the new Person object.
         * @return  The created Person object.
         */
        public Person build() {
            return built;
        }
    }

    /**
     * This setter method should only be used by unit tests.
     * @param id
     */
    protected void setId(Long id) {
        this.id = id;
    }
}

Creating the Repository

Implementing a repository which provides CRUD operations for the Person model object is pretty straightforward. All you have to do is to create an interface which extends the JpaRepository interface. The JpaRepository interface is a JPA specific extension to the Repository interface and it gives you the access to following methods which are used to implement the CRUD application:

  • delete(T entity) which deletes the entity given as a parameter.
  • findAll() which returns a list of entities.
  • findOne(ID id) which returns the entity using the id given a parameter as a search criteria.
  • save(T entity) which saves the entity given as a parameter.

The source code of my PersonRepository interface is given in following:

import org.springframework.data.jpa.repository.JpaRepository;

/**
 * Specifies methods used to obtain and modify person related information
 * which is stored in the database.
 * @author Petri Kainulainen
 */
public interface PersonRepository extends JpaRepository<Person, Long> {
}

Using the Created Repository

You have now created both the model object and the repository which is needed to communicate with the database. The next step is to implement a service class which acts as an intermediary between the controllers and the implemented repository. The structure of the service layer is described next.

The PersonDTO is a simple DTO object which is used as a form object in my example application. Its source code is given in following:

import org.apache.commons.lang.builder.ToStringBuilder;
import org.hibernate.validator.constraints.NotEmpty;

/**
 * A DTO object which is used as a form object
 * in create person and edit person forms.
 * @author Petri Kainulainen
 */
public class PersonDTO {
    
    private Long id;

    @NotEmpty
    private String firstName;

    @NotEmpty
    private String lastName;

    public PersonDTO() {

    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }
}

The PersonService interface specifies the methods which are provided by the actual implementation. Its source code is given in following:

/**
 * Declares methods used to obtain and modify person information.
 * @author Petri Kainulainen
 */
public interface PersonService {

    /**
     * Creates a new person.
     * @param created   The information of the created person.
     * @return  The created person.
     */
    public Person create(PersonDTO created);

    /**
     * Deletes a person.
     * @param personId  The id of the deleted person.
     * @return  The deleted person.
     * @throws PersonNotFoundException  if no person is found with the given id.
     */
    public Person delete(Long personId) throws PersonNotFoundException;

    /**
     * Finds all persons.
     * @return  A list of persons.
     */
    public List<Person> findAll();

    /**
     * Finds person by id.
     * @param id    The id of the wanted person.
     * @return  The found person. If no person is found, this method returns null.
     */
    public Person findById(Long id);

    /**
     * Updates the information of a person.
     * @param updated   The information of the updated person.
     * @return  The updated person.
     * @throws PersonNotFoundException  if no person is found with given id.
     */
    public Person update(PersonDTO updated) throws PersonNotFoundException;
}

The source code of the RepositoryPersonService class which implements the PersonService interface is given in following:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * This implementation of the PersonService interface communicates with
 * the database by using a Spring Data JPA repository.
 * @author Petri Kainulainen
 */
@Service
public class RepositoryPersonService implements PersonService {
    
    private static final Logger LOGGER = LoggerFactory.getLogger(RepositoryPersonService.class);
    
    @Resource
    private PersonRepository personRepository;

    @Transactional
    @Override
    public Person create(PersonDTO created) {
        LOGGER.debug("Creating a new person with information: " + created);
        
        Person person = Person.getBuilder(created.getFirstName(), created.getLastName()).build();
        
        return personRepository.save(person);
    }

    @Transactional(rollbackFor = PersonNotFoundException.class)
    @Override
    public Person delete(Long personId) throws PersonNotFoundException {
        LOGGER.debug("Deleting person with id: " + personId);
        
        Person deleted = personRepository.findOne(personId);
        
        if (deleted == null) {
            LOGGER.debug("No person found with id: " + personId);
            throw new PersonNotFoundException();
        }
        
        personRepository.delete(deleted);
        return deleted;
    }

    @Transactional(readOnly = true)
    @Override
    public List<Person> findAll() {
        LOGGER.debug("Finding all persons");
        return personRepository.findAll();
    }

    @Transactional(readOnly = true)
    @Override
    public Person findById(Long id) {
        LOGGER.debug("Finding person by id: " + id);
        return personRepository.findOne(id);
    }

    @Transactional(rollbackFor = PersonNotFoundException.class)
    @Override
    public Person update(PersonDTO updated) throws PersonNotFoundException {
        LOGGER.debug("Updating person with information: " + updated);
        
        Person person = personRepository.findOne(updated.getId());
        
        if (person == null) {
            LOGGER.debug("No person found with id: " + updated.getId());
            throw new PersonNotFoundException();
        }
        
        person.update(updated.getFirstName(), updated.getLastName());

        return person;
    }

    /**
     * This setter method should be used only by unit tests.
     * @param personRepository
     */
    protected void setPersonRepository(PersonRepository personRepository) {
        this.personRepository = personRepository;
    }
}

The last part of this step was to write unit tests for the RepositoryPersonService class. The source code of these unit tests is given in following:

import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;

import static junit.framework.Assert.assertEquals;
import static org.mockito.Mockito.*;

public class RepositoryPersonServiceTest {

    private static final Long PERSON_ID = Long.valueOf(5);
    private static final String FIRST_NAME = "Foo";
    private static final String FIRST_NAME_UPDATED = "FooUpdated";
    private static final String LAST_NAME = "Bar";
    private static final String LAST_NAME_UPDATED = "BarUpdated";
    
    private RepositoryPersonService personService;

    private PersonRepository personRepositoryMock;

    @Before
    public void setUp() {
        personService = new RepositoryPersonService();

        personRepositoryMock = mock(PersonRepository.class);
        personService.setPersonRepository(personRepositoryMock);
    }
    
    @Test
    public void create() {
        PersonDTO created = PersonTestUtil.createDTO(null, FIRST_NAME, LAST_NAME);
        Person persisted = PersonTestUtil.createModelObject(PERSON_ID, FIRST_NAME, LAST_NAME);
        
        when(personRepositoryMock.save(any(Person.class))).thenReturn(persisted);
        
        Person returned = personService.create(created);

        ArgumentCaptor<Person> personArgument = ArgumentCaptor.forClass(Person.class);
        verify(personRepositoryMock, times(1)).save(personArgument.capture());
        verifyNoMoreInteractions(personRepositoryMock);

        assertPerson(created, personArgument.getValue());
        assertEquals(persisted, returned);
    }
    
    @Test
    public void delete() throws PersonNotFoundException {
        Person deleted = PersonTestUtil.createModelObject(PERSON_ID, FIRST_NAME, LAST_NAME);
        when(personRepositoryMock.findOne(PERSON_ID)).thenReturn(deleted);
        
        Person returned = personService.delete(PERSON_ID);
        
        verify(personRepositoryMock, times(1)).findOne(PERSON_ID);
        verify(personRepositoryMock, times(1)).delete(deleted);
        verifyNoMoreInteractions(personRepositoryMock);
        
        assertEquals(deleted, returned);
    }
    
    @Test(expected = PersonNotFoundException.class)
    public void deleteWhenPersonIsNotFound() throws PersonNotFoundException {
        when(personRepositoryMock.findOne(PERSON_ID)).thenReturn(null);
        
        personService.delete(PERSON_ID);
        
        verify(personRepositoryMock, times(1)).findOne(PERSON_ID);
        verifyNoMoreInteractions(personRepositoryMock);
    }
    
    @Test
    public void findAll() {
        List<Person> persons = new ArrayList<Person>();
        when(personRepositoryMock.findAll()).thenReturn(persons);
        
        List<Person> returned = personService.findAll();
        
        verify(personRepositoryMock, times(1)).findAll();
        verifyNoMoreInteractions(personRepositoryMock);
        
        assertEquals(persons, returned);
    }
    
    @Test
    public void findById() {
        Person person = PersonTestUtil.createModelObject(PERSON_ID, FIRST_NAME, LAST_NAME);
        when(personRepositoryMock.findOne(PERSON_ID)).thenReturn(person);
        
        Person returned = personService.findById(PERSON_ID);
        
        verify(personRepositoryMock, times(1)).findOne(PERSON_ID);
        verifyNoMoreInteractions(personRepositoryMock);
        
        assertEquals(person, returned);
    }
    
    @Test
    public void update() throws PersonNotFoundException {
        PersonDTO updated = PersonTestUtil.createDTO(PERSON_ID, FIRST_NAME_UPDATED, LAST_NAME_UPDATED);
        Person person = PersonTestUtil.createModelObject(PERSON_ID, FIRST_NAME, LAST_NAME);
        
        when(personRepositoryMock.findOne(updated.getId())).thenReturn(person);
        
        Person returned = personService.update(updated);
        
        verify(personRepositoryMock, times(1)).findOne(updated.getId());
        verifyNoMoreInteractions(personRepositoryMock);
        
        assertPerson(updated, returned);
    }
    
    @Test(expected = PersonNotFoundException.class)
    public void updateWhenPersonIsNotFound() throws PersonNotFoundException {
        PersonDTO updated = PersonTestUtil.createDTO(PERSON_ID, FIRST_NAME_UPDATED, LAST_NAME_UPDATED);
        
        when(personRepositoryMock.findOne(updated.getId())).thenReturn(null);

        personService.update(updated);

        verify(personRepositoryMock, times(1)).findOne(updated.getId());
        verifyNoMoreInteractions(personRepositoryMock);
    }

    private void assertPerson(PersonDTO expected, Person actual) {
        assertEquals(expected.getId(), actual.getId());
        assertEquals(expected.getFirstName(), actual.getFirstName());
        assertEquals(expected.getLastName(), expected.getLastName());
    }
}

What is Next?

I have now demonstrated to you how you can implement a simple CRUD application with Spring Data JPA. If you are interested of seeing my fully functional example in action, you can get it from Github. The third part of my Spring Data JPA tutorial describes how you can create custom queries with query methods.

If you want to learn more about Spring Data JPA, you should read all parts of my Spring Data JPA tutorial.
If you enjoyed reading this blog post, you should follow me on Twitter:

About the Author

Petri Kainulainen is passionate about software development and continuous improvement. He is specialized in software development with the Spring Framework and is the author of Spring Data book.

About Petri Kainulainen →

155 comments… add one

  • Great stuff.

    Reply
  • 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

    Reply
    • 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.

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

    Reply
    • 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.

      Reply
      • 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

        Reply
        • 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.

          Reply
  • 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?

    Reply
    • 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?

      Reply
      • 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.

        Reply
        • 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.

          Reply
  • 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

    Reply
    • 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.

      Reply
      • 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.

        Reply
        • 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.

          Reply
          • 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

          • 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)?

          • 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

          • 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

  • 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

    Reply
    • 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/.

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

        Reply
        • 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:

          Reply
          • 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.

          • 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.

      • 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

        Reply
  • 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

    Reply
    • 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.

      Reply
  • 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

    Reply
    • 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?

      Reply
  • 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?

    Reply
    • 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).

      Reply
  • 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

    Reply
    • 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).

      Reply
  • 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

    Reply
    • 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.

      Reply
  • 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

    Reply
    • 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.

      Reply
  • 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?

    Reply
    • 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.

      Reply
      • 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

        Reply
        • 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.

          Reply
          • 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.

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

          • 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.

          • 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?

          • 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.

  • 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

    Reply
    • 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?

      Reply
      • 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

        Reply
        • 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.

          Reply
  • 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?

    Reply
  • 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

    Reply
    • 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.

      Reply
  • 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.

    Reply
    • 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.

      Reply
  • Thanks!

    Reply
    • You are welcome.

      Reply
  • 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!

    Reply
    • 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!

      Reply
  • 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

    Reply
    • 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.

      Reply
  • 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,

    Reply
    • wupss i meant Integration Test

      Reply
      • 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.

        Reply
    • 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.

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

    Reply
  • 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.

    Reply
    • 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!

      Reply
  • 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/

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

      Reply
  • 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?

    Reply
    • 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).

      Reply
      • 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.

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

          Reply
        • 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.
          Reply
  • 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`?

    Reply
  • 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.

    Reply
  • 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.

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

      Reply
  • 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

    Reply
    • 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.

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

    Reply
  • 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?

    Reply
    • 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. :)

      Reply
  • 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

    Reply
    • 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.

      Reply
  • 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.

    Reply
    • 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.

      Reply
  • @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!!!

    Reply
    • 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.

      Reply
  • 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

    Reply
    • 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);
      
      
      Reply
  • 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

    Reply
    • 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.

      Reply
      • 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

        Reply
  • 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. :)

    Reply
  • 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

    Reply
    • 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 ApplicationContext 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.

      Reply
  • 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

    Reply
    • 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).

      Reply
      • 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

        Reply
      • 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?

        Reply
        • 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:

          Reply
  • 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.

    Reply
  • 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.

    Reply
    • 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.

      Reply
  • 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?

    Reply
    • 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.

      Reply
      • Thank you for your prompt reply. You explanation helped.

        Reply
  • 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

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

    Reply
    • 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).

      Reply
      • 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.

        Reply
        • 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:

          Reply
  • 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

    Reply
    • 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).

      Reply
      • 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

        Reply
        • 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?

          Reply
          • 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 :)

          • 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.

  • 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?

    Reply
  • 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

    Reply
    • 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.

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

    Reply
    • 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.

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

    Reply
    • 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).

      Reply
      • 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)?

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

          Reply
          • 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.

          • 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?

          • 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.

  • 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?

    Reply
    • 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.

      Reply
  • 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

    Reply
    • 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.

      Reply
  • 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

    Reply
    • 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.

      Reply
      • 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.

        Reply
        • Don’t know why I posted as anonimus… sorry about that.

          Reply
        • 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!

          Reply
          • 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.

          • 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.

          • 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

          • 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?

          • 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.

          • 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.

          • 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.

          • 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?

Leave a Comment