Spring Data Custom Repository
Spring Data Custom Repository
In the previous blog we have discussed how to add repository in the spring boot application.
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
User findById(final Long id);
}
For this findById method spring will generate the query for us. To do it spring needs to understand the method name, like find + by + Id. And the id field in the User entity should be the same.
So now let’s assume that we want to create the custom implementation. For it we need to create the UserRepositoryCustom.java interface.
import com.springjpa.example.model.User; import java.util.List; public interface UserRepositoryCustom { List<User> findAllByCountryId(Long id); }
In the User entity we have Country field, and let’s say we want to find all users for specific country. Let’s create the implementation for this interface.
import com.springjpa.example.model.User; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.TypedQuery; import java.util.List; public class UserRepositoryCustomImpl implements UserRepositoryCustom { @PersistenceContext private EntityManager em; @Override public List<User> findAllByCountryId(Long countryId) { String sql = "select u from User u where u.country.id = :countryId"; final TypedQuery<User> query = em.createQuery(sql, User.class); query.setParameter("countryId", countryId); return query.getResultList(); } }
[addToAppearHere]
We need to use EntityManager interface to interact with persistence context.
And the last thing we need to do change the UserRepository.java interface to extend the new Custom interface:
@Repository public interface UserRepository extends JpaRepository<User, Long>, UserRepositoryCustom { User findById(final Long id); }
And we need to add the Country.java entity:
import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name = "country") public class Country { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "id") private Long id; @Column(name = "name", nullable = false) private String name; public Country() { } public Country(String name) { this.name = name; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Country{" + "id=" + id + ", name='" + name + '\'' + '}'; } }
And the CountryRepository class:
import com.springjpa.example.model.Country; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface CountryRepository extends JpaRepository<Country, Long> { }
The next step is to update the User.java:
import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; @Entity @Table(name = "user") public class User { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "id") private Long id; @Column(name = "name", nullable = false) private String name; @ManyToOne() @JoinColumn(name = "country_id") private Country country; public User() { } public User(String name, Country country) { this.name = name; this.country = country; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Country getCountry() { return country; } public void setCountry(Country country) { this.country = country; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", country=" + country + '}'; } }
[addToAppearHere]
And the last thing is to call the new added method:
import com.springjpa.example.model.Country;
import com.springjpa.example.model.User;
import com.springjpa.example.repository.CountryRepository;
import com.springjpa.example.repository.UserRepository;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import java.util.List;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
@Bean
public CommandLineRunner commandLineRunner(UserRepository userRepository, CountryRepository countryRepository) {
return new MyCommandLineRunner(userRepository, countryRepository);
}
private static class MyCommandLineRunner implements CommandLineRunner {
private final UserRepository userRepository;
private final CountryRepository countryRepository;
public MyCommandLineRunner(UserRepository userRepository, CountryRepository countryRepository) {
this.userRepository = userRepository;
this.countryRepository = countryRepository;
}
@Override
public void run(String... args) throws Exception {
// save country
Country germany = new Country("Germany");
Country usa = new Country("USA");
germany = countryRepository.save(germany);
usa = countryRepository.save(usa);
// save some users
userRepository.save(new User("user1", germany));
userRepository.save(new User("user2", germany));
userRepository.save(new User("user3", usa));
// get all users
System.out.println("Getting all users...");
userRepository.findAll().forEach(System.out::println);
// get the user by id
System.out.println("Get the user by id");
User user = userRepository.findById(1L);
System.out.println(user);
// get the user by id
System.out.println("Get the user by id");
List usersInGermany = userRepository.findAllByCountryId(germany.getId());
usersInGermany.forEach(System.out::println);
}
}
}
The full working example you can find in the github.