Set up a maven web project in Intellij with Spring and JPA - Part Five

Here we go for part 5 of this tutorial series! This part will cover our Data Acces Object Layer (DAO).
We will be mainly talking about CRUD (create,update,delete) operations using JPA and Spring.


I should start by saying that we will use an Interface and an Implementation for each Entity.
This way we can easily switch database providers later if we would like to.

The PostDao interface:
package blog.dao;

import blog.domain.Post;
import java.util.List;

public interface PostDao {
    List<Post> findAllPosts();
    Post findPostByPostId(Long postId);

    void create(Post post);

    void remove(Post post);

    void update(Post post);

    List<Post> findMostRecentPosts();
}

note that we created crud methods and some other selection methods we'll need later.


Now that we have our interface let's move on with the actual implementation, this is where it gets interesting.

@Repository
public class PostDaoImpl implements PostDao {
    private EntityManager em;

    @PersistenceContext
    void setEntityManager(EntityManager entityManager) {
        this.em = entityManager;
    }

    public void create(Post post) {
        em.persist(post);
    }

    public void remove(Post post) {
        em.remove(post);
    }

    public void update(Post post) {
        em.merge(post);
    }

    public Post findPostByPostId(Long postId) {
        return em.find(Post.class, postId);
    }

    
    public List<Post> findAllPosts() {
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<Post> c = cb.createQuery(Post.class);

        Root<Post> post = c.from(Post.class);

        c.select(post);

        TypedQuery<Post> tq = em.createQuery(c);

        return tq.getResultList();
    }
    public List<Post> findMostRecentPosts() {
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<Post> c = cb.createQuery(Post.class);

        Root<Post> post = c.from(Post.class);

        c.select(post);
        c.orderBy(cb.desc(post.get("postDate")));

        TypedQuery<Post> tq = em.createQuery(c);
        tq.setMaxResults(5);
        return tq.getResultList();
    } 

}


Lots and lot's of things to be explained here :) Let's start out with the basics, we tell Spring "Hey this class takes care of database actions" by adding the @Repository annotation.
Further we tell spring to autowire the persistence context via setter dependency injection using the @PersistenceContext!
The cool thing about Spring 3.1 is that you no longer have to define a Persistence.xml!
We can use crud methods out of the box using em.persist/merge/remove respectively by just passing the object we want persisted.
Also selecting on primary key is very easy just use the find method from the entity manager and pass the class you are selecting and the primary key value.

The remaining queries show usage of the jpa criteria api.

The same routing should be done for the Comment entity too, I'll provide the source code here:
CommentDao:
package blog.dao;

import blog.domain.Comment;
import java.util.List;

public interface CommentDao {
     void create(Comment comment);
     List<Comment> findCommentsForPost(long postId);
 }


CommentDaoImpl:
package blog.dao;


import blog.domain.Comment;
import org.springframework.stereotype.Repository;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.ParameterExpression;
import javax.persistence.criteria.Root;
import java.util.List;

@Repository
public class CommentDaoImpl implements CommentDao {

    private EntityManager em;

    @PersistenceContext
    void setEntityManager(EntityManager entityManager) {
        this.em = entityManager;
    }

    public void create(Comment comment) {
        em.persist(comment);
    }

    public List<Comment> findCommentsForPost(long postId) {
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<Comment> c = cb.createQuery(Comment.class);
        Root<Comment> comment = c.from(Comment.class);
        c.select(comment);
        ParameterExpression<Long> pe = cb.parameter(Long.class,"postId");
        c.where(cb.equal(comment.get("post").get("postId"),pe));
        TypedQuery<Comment> tq = em.createQuery(c);
        tq.setParameter("postId",postId);

        return tq.getResultList();
    }
}


That's all, we have now configured our Database layer! See you at the next tutorial.

More about this tutorial series can be found here:
Set up a maven web project in Intellij with Spring and JPA - Part One (Project setup)
Set up a maven web project in Intellij with Spring and JPA - Part Two (Maven setup)
Set up a maven web project in Intellij with Spring and JPA - Part Three (ORM mapping)
Set up a maven web project in Intellij with Spring and JPA - Part Four (Spring Configuration)
Set up a maven web project in Intellij with Spring and JPA - Part Six (Configuring Spring MVC)
Set up a maven web project in Intellij with Spring and JPA - Part Seven (Implementing Spring MVC)