Announcement Announcement Module
Collapse
No announcement yet.
Avoiding data related code spilling out into the service layer Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Avoiding data related code spilling out into the service layer

    Hi,

    I'm trying to have all data related code reside in the repository layer and not spill out into the service layer.

    I have a service method using only primitive types:
    Code:
    public List<Admin> search(String searchTerm, int pageIndex, int pageSize) {
        return adminRepository.search(searchTerm, pageIndex, pageSize);
    }
    And a repository method routing it to a standard Jpa method:
    Code:
    public List<Admin> search(String searchTerm, int pageIndex, int pageSize) {
        Pageable pageSpec = buildPageSpecification(pageIndex, pageSize);
        Page wanted = search(searchTerm, pageSpec);
        return wanted.getContent();
    }
    With the following method in the repository interface:
    Code:
    @Query("SELECT a FROM Admin a WHERE LOWER(a.firstname) LIKE LOWER(:searchTerm) OR LOWER(a.lastname) LIKE LOWER(:searchTerm) ORDER BY a.lastname ASC, a.firstname ASC")
    public List search(@Param("searchTerm") String searchTerm, Pageable page);
    But the service method sees the repository interface method instead of the repository implementation one.

  • #2
    Originally posted by stephaneeybert View Post
    Hi,

    I'm trying to have all data related code reside in the repository layer and not spill out into the service layer.

    ...
    I think what you are trying to say is that you want to limit org.spring.data dependencies to the repository layer by using "pageIndex" and "pageSize" instead of a Pageable in the service layer. Is that right?

    Another question to clarify things: in which concrete class are you putting the implementation of your "search(String, int, int)" method?

    Code:
    public List<Admin> search(String searchTerm, int pageIndex, int pageSize) { ... }
    I took your code outline and played with Custom Implementations and Custom Behaviour for all Repositories but could not fit your design into those.

    The only two things I can think of off the top of my head are (1) to wrap/extend org.springframework.data.domain.PageRequest in a custom class in your repository package and use your custom Pageable class in your service layer. For example,

    Code:
    package your.repository;
    ...
    public class MyPageable extends PageRequest {
    
        // ... define the constructors which call those of the superclass here ...
    }
    It's a bit clumsy, and duplicative.

    The second approach would be to create a "helper" class in your repository package which would define the "List<Admin> search(String, int, int)" method with an additional parameter being the AdminRepository.

    Code:
    public class MyAdminRepoHelper {
    ...
        public List<Admin> search(String searchTerm, int pageIndex, int pageSize, AdminRepository repo) { 
            return repo.search(searchTerm, new PageRequest(pageIndex, pageSize);
        }
    }

    Finally, what is the motivation for not using Spring data classes in the service layer? After all, you have probably already committed to using Spring Data, and possibly Spring MVC, Spring @Service, etc.

    Comment


    • #3
      Thanks for that rich comment, a quick reply here, I have kids around me, yes that's right, I was trying to limit org.spring.data dependencies to the repository layer.

      I thought it'd be cleaner and the proper way to go, but then as you say the effort may make little sense.

      I was putting the "search(String, int, int)" method in the AdminRepositoryImpl class.

      Here it is:
      Code:
      	public List<Admin> search(String searchTerm, int pageIndex, int pageSize) {
      		Pageable pageSpec = buildPageSpecification(pageIndex, pageSize);
      		List<Admin> wanted = search(searchTerm, pageSpec);
      		return wanted;
      	}
      I also wonder if I should have a GenericRepository and its GenericRepositoryImpl as a base (NoRepositoryBean-ed) to all domain class repositories ? Have you done this in a real world application ?

      My aim is to write the data access layer for a CMS / LMS consisting of 116 tables. The schema is really clean and the PHP implementation is crusing in production. But a Spring Data Jpa implementation would be nice to have as a first building block on which to have a RESTful interface.
      Last edited by stephaneeybert; Apr 30th, 2013, 01:44 PM.

      Comment


      • #4
        Actually, the pagination API exists to avoid using primitives to carry around information that actually embodies a higher level concept like pagination. That's why these types reside in a domain package. What's the reason you seem to like sacrificing expressive code over a interface dependency? (Serious question, no trolling.)

        I'd recommend to use Pageable and Page interfaces throughout the codebase and try to rely on PageRequest only sparingly (e.g. there's helper classes that allow Spring MVC to create instances from request parameters automatically).

        Comment


        • #5
          Thanks Oliver for your input ! It feels really nice to see the author of the API caring to newbies.

          Comment

          Working...
          X