Deal of the Day

Home » Main » Manning Forums » 2008 » Spring in Practice

Thread: No AbstractJpaDao [Spring Data Solution]

Reply to this Thread Reply to this Thread Search Forum Search Forum Back to Thread List Back to Thread List

Permlink Replies: 4 - Pages: 1 - Last Post: Dec 31, 2011 4:33 PM by: bbaron
dalrympm

Posts: 19
From: San Francisco, CA
Registered: 10/26/08
No AbstractJpaDao [Spring Data Solution]
Posted: Dec 17, 2011 12:23 AM
  Click to reply to this thread Reply

I seem to recall previous revisions of this book included an AbstractJpaDao example. Section 2.5 suggests the similarity to the the Hibernate example but doesn't seem to create an abstract class similar to the AbstractHbnDao. I guess that could be left as an exercise for the reader but it might be helpful to have some suggestion of the practice.

Message was edited by:
dalrympm

willie.wheeler


Posts: 110
From: Sammamish, WA
Registered: 9/30/08
Re: No AbstractJpaDao
Posted: Dec 17, 2011 12:43 AM   in response to: dalrympm in response to: dalrympm
  Click to reply to this thread Reply

Hey Mike,

I'm pretty sure that the earlier versions of the book didn't have anything around JPA as a provider. (We've always used the JPA annotations, but not EntityManager and such.)

The reason that there's no AbstractJpaDao example is that Spring Data JPA creates the JPA implementation automatically for you as long as you implement the JpaRepository interface. It uses Java dynamic proxies. So you don't have to extend any abstract class. I probably need to make that a little clearer in the book. Let me know though whether that explanation makes sense.

Thanks for all the good feedback.
Willie

dalrympm

Posts: 19
From: San Francisco, CA
Registered: 10/26/08
Re: No AbstractJpaDao
Posted: Dec 17, 2011 11:15 PM   in response to: willie.wheeler in response to: willie.wheeler
  Click to reply to this thread Reply

Yeah, it looks like I created my own AbstractJpaDao that mimicked the AbstractHbnDao. The Spring Data JPA project certainly looks compelling but readers may run into the same road block (ok, maybe speed bump) I did which is figuring out how to model the Account type with the password isolation. My current thinking is to have a concrete AccountDao that delegates most of the responsibilities to the auto-generated Spring Data JPA DAO while handling the password functionality using the JdbcTemplate. Maybe that's a topic for another thread...

dalrympm

Posts: 19
From: San Francisco, CA
Registered: 10/26/08
Re: No AbstractJpaDao
Posted: Dec 31, 2011 2:45 AM   in response to: dalrympm in response to: dalrympm
  Click to reply to this thread Reply

After reading through the Spring Data docs, I came up with a means of injecting a JdbcTemplate while maintaining the elegance of Spring Data, here were my steps. Note that I use AccountRepository instead of AccountDao since that seems to be the Spring Data norm.

1. I created an interface called AccountRepositoryJdbc that contains the methods I require for password interactions. No Spring Data dependencies here and the interface name is not critical:

public interface AccountRepositoryJdbc {
public Account createAccount(Account account, String password);
public Account updateAccountPassword(Account account, String password);
public String findPasswordByUsername(String username);
}

2. Create an AccountRepository interface following the Spring Data format as described in the book with the exception that it extends the previously defined AccountRepositoryJdbc interface.


public interface AccountRepository extends JpaRepository<Account, Long>, AccountRepositoryJdbc{
Account findByUsername(String username);
}


3. Here's the cool part, I created an AccountRepositoryImpl that implements the AccountRepositoryJdbc and injects an AccountRepository as well as the JdbcTemplate, PasswordEncoder and SaltSource. The name here IS critical since it is an indication to Spring Data that the generated DAO/Repository should extend this implementation (as far as I understand it at least). Since that extension happens on the fly you don't actually have access to the CRUD operations you need so you have to inject the AccountRepository back into this implementation. A little strange but cool.


public class AccountRepositoryImpl implements AccountRepositoryJdbc{
private static final String FIND_PASSWORD_SQL = "SELECT password FROM accounts WHERE username=?";
private static final String SET_PASSWORD_SQL = "UPDATE accounts SET password=? WHERE username=?";

@Autowired private AccountRepository accountRepository;
@Autowired private JdbcTemplate jdbcTemplate;
@Autowired private PasswordEncoder passwordEncoder;
@Autowired private SaltSource saltSource;

@Override
public Account createAccount(Account account, String password) {
accountRepository.save(account);
updateAccountPassword(account, password);
return account;
}
@Override
public Account updateAccountPassword(Account account, String password) {
Object salt = saltSource.getSalt(new UserDetailsAdapter(account));
String encPassword = passwordEncoder.encodePassword(password, salt);
jdbcTemplate.update(SET_PASSWORD_SQL, encPassword, account.getUsername());
return account;
}
@Override
public String findPasswordByUsername(String username) {
return jdbcTemplate.queryForObject(FIND_PASSWORD_SQL, String.class, username);
}
}


Willie, thanks for spending a little time on Spring Data, it's really quite wonderful.

Mike

bbaron

Posts: 64
From: earth
Registered: 9/28/08
Re: No AbstractJpaDao
Posted: Dec 31, 2011 4:33 PM   in response to: dalrympm in response to: dalrympm
  Click to reply to this thread Reply

Ah, I smell a new design pattern here. The "self-injection" pattern maybe?

Legend
Gold: 300 + pts
Silver: 100 - 299 pts
Bronze: 25 - 99 pts
Manning Author
Manning Staff
Manning Developmental Editor