
Data access objects
We need to refactor the JdbcEventDao.java file with a new name, JpaEventDao.java, so we can replace the JDBC SQL code with our new Spring Data code. Let's take a look at the following steps:
- Specifically, we need to add the new EventRepository interface, and replace the SQL code with the new ORM repository, as shown in the following code:
//com/packtpub/springsecurity/dataaccess/JpaEventDao.java
package com.packtpub.springsecurity.dataaccess;
import com.packtpub.springsecurity.domain.CalendarUser;
import com.packtpub.springsecurity.domain.Event;
import com.packtpub.springsecurity.repository.EventRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
...
@Repository
public class JpaEventDao implements EventDao {
private EventRepository repository;
@Autowired
public JpaEventDao(EventRepository repository) {
if (repository == null) {
throw new IllegalArgumentException("repository
cannot be null");
}
this.repository = repository;
}
@Override
@Transactional(readOnly = true)
public Event getEvent(int eventId) {
return repository.findOne(eventId);
}
@Override
public int createEvent(final Event event) {
...
final Calendar when = event.getWhen();
if(when == null) {
throw new IllegalArgumentException("event.getWhen()
cannot be null");
}
Event newEvent = repository.save(event);
...
}
@Override
@Transactional(readOnly = true)
public List<Event> findForUser(final int userId) {
Event example = new Event();
CalendarUser cu = new CalendarUser();
cu.setId(userId);
example.setOwner(cu);
return repository.findAll(Example.of(example));
}
@Override
@Transactional(readOnly = true)
public List<Event> getEvents() {
return repository.findAll();
}
}
- At this point, we need to refactor the DAO classes to support the new CrudRepository interfaces we have created. Let's begin with refactoring the JdbcCalendarUserDao.java file. First, we can rename the file to JpaCalendarUserDao.java to indicate that this is using JPA, and not standard JDBC:
//com/packtpub/springsecurity/dataaccess/JpaCalendarUserDao.java
package com.packtpub.springsecurity.dataaccess;
... omitted for brevity ...
@Repository
public class JpaCalendarUserDao
implements CalendarUserDao {
private CalendarUserRepository userRepository;
private RoleRepository roleRepository;
@Autowired
public JpaCalendarUserDao(CalendarUserRepository repository,
RoleRepository roleRepository) {
if (repository == null) {
throw new IllegalArgumentException("repository
cannot be null");
}
if (roleRepository == null) {
throw new IllegalArgumentException("roleRepository
cannot be null");
}
this. userRepository = repository;
this.roleRepository = roleRepository;
}
@Override
@Transactional(readOnly = true)
public CalendarUser getUser(final int id) {
return userRepository.findOne(id);
}
@Override
@Transactional(readOnly = true)
public CalendarUser findUserByEmail(final String email) {
if (email == null) {
throw new IllegalArgumentException
("email cannot be null");
}
try {
return userRepository.findByEmail(email);
} catch (EmptyResultDataAccessException notFound) {
return null;
}
}
@Override
@Transactional(readOnly = true)
public List<CalendarUser> findUsersByEmail(final String email) {
if (email == null) {
throw new IllegalArgumentException("email
cannot be null");
}
if ("".equals(email)) {
throw new IllegalArgumentException("email
cannot be empty string");
}
return userRepository.findAll();
}
@Override
public int createUser(final CalendarUser userToAdd) {
if (userToAdd == null) {
throw new IllegalArgumentException("userToAdd
cannot be null");
}
if (userToAdd.getId() != null) {
throw new IllegalArgumentException("userToAdd.getId()
must be null when creating a "+
CalendarUser.class.getName());
}
Set<Role> roles = new HashSet<>();
roles.add(roleRepository.findOne(0));
userToAdd.setRoles(roles);
CalendarUser result = userRepository.save(userToAdd);
userRepository.flush();
return result.getId();
}
}
As you can see in the preceding code, the update fragments to leverage the amount needed for JPA are quite a bit less than the required code for JDBC. This means we can focus on business logic and not worry about the plumbing.
- We continue by refactoring the JdbcEventDao.java file. First, we can rename the file to JpaEventDao.java, to indicate that this is using JPA and not standard JDBC, as follows:
//com/packtpub/springsecurity/dataaccess/JpaEventDao.java
package com.packtpub.springsecurity.dataaccess;
... omitted for brevity ...
@Repository
public class JpaEventDao implements EventDao {
private EventRepository repository;
@Autowired
public JpaEventDao(EventRepository repository) {
if (repository == null) {
throw new IllegalArgumentException("repository
cannot be null");
}
this.repository = repository;
}
@Override
@Transactional(readOnly = true)
public Event getEvent(int eventId) {
return repository.findOne(eventId);
}
@Override
public int createEvent(final Event event) {
if (event == null) {
throw new IllegalArgumentException("event cannot be null");
}
if (event.getId() != null) {
throw new IllegalArgumentException
("event.getId() must be null when creating a new Message");
}
final CalendarUser owner = event.getOwner();
if (owner == null) {
throw new IllegalArgumentException("event.getOwner()
cannot be null");
}
final CalendarUser attendee = event.getAttendee();
if (attendee == null) {
throw new IllegalArgumentException("attendee.getOwner()
cannot be null");
}
final Calendar when = event.getWhen();
if(when == null) {
throw new IllegalArgumentException
("event.getWhen()cannot be null");
}
Event newEvent = repository.save(event);
return newEvent.getId();
}
@Override
@Transactional(readOnly = true)
public List<Event> findForUser(final int userId) {
Event example = new Event();
CalendarUser cu = new CalendarUser();
cu.setId(userId);
example.setOwner(cu);
return repository.findAll(Example.of(example));
}
@Override
@Transactional(readOnly = true)
public List<Event> getEvents() {
return repository.findAll();
}
}
In the preceding code, the update fragments to leverage the JPA repositories have been placed in bold, so now the Event and CalendarUser objects are mapped to our underlying RDBMS.
The application will not work at this point, but this can still be considered a marker point before we continue on to the next steps of conversion.
At this point, your source code should look the same as chapter05.03-calendar.