Implement HibernateUserRepository

As mentioned, Spring Data JPA will instantiate EntityManager for us. EntityManager is an interface of JPA. And, in our application, Hibernate is the underlying implementation. Hibernate offers a more powerful API than JPA. For example, the org.hibernate.query.Query interface supports Generics while the javax.persistence.Query interface does not. In this book, we will use Hibernate's API in our repository implementation most of the time.

To make things easier, let's first create an abstract base class, HibernateSupport, to retrieve an instance of org.hibernate.Session from EntityManager. Here is how it looks:

...
abstract class HibernateSupport {

EntityManager entityManager;

HibernateSupport(EntityManager entityManager) {
this.entityManager = entityManager;
}

Session getSession() {
return entityManager.unwrap(Session.class);
}
}

As you can see, we ask Spring to inject the EntityManager instance here and then inside the getSession() method, which returns an instance of org.hibernate.Session, we use the unwrap() method of EntityManager to get an instance of the Hibernate session.

And the following is how HibernateUserRepository looks:

...
@Repository
public class HibernateUserRepository extends HibernateSupport
implements UserRepository {

public HibernateUserRepository(EntityManager entityManager) {
super(entityManager);
}

@Override
public User findByUsername(String username) {
Query<User> query = getSession().createQuery(
"from User where username = :username", User.class);
query.setParameter("username", username);
return query.uniqueResult();
}

@Override
public User findByEmailAddress(String emailAddress) {
Query<User> query = getSession().createQuery(
"from User where emailAddress = :emailAddress", User.class);
query.setParameter("emailAddress", emailAddress);
return query.uniqueResult();
}

@Override
public void save(User user) {
entityManager.persist(user);
entityManager.flush();
}
}

As you can see, besides the save() method where we use the EntityManager API directly, for the other two find* methods, we use Hibernate's API. It is true that there is boilerplate code in here. The trade-off is that we keep the infrastructure implementation details out of our domain model.

Now, let's run the mvn clean install command to make sure everything works before committing the code. As you should see, it is a successful build. The following is the commit record on GitHub:

Figure 9.13: Implement registration in domain model and repository commit
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.129.217.5