2015-03-31 6 views
13

Ist es möglich, projection beim direkten Aufruf der Datenrepository-Methode anzugeben? Hier Repository Code - Note würde ich es nicht über REST aussetzen möchte, stattdessen würde ich es in der Lage sein möchte Anruf von einem Dienst oder Controller:Wie werden Spring Data-Projektionen in Spring-MVC-Controllern angewendet?

@RepositoryRestResource(exported = false) 
public interface UsersRepository extends PagingAndSortingRepository<User, Long> { 

    @Query(value = "SELECT u FROM User u WHERE ....") 
    public Page<User> findEmployeeUsers(Pageable p); 
} 

Dann in einem Controller ich dies tun:

@PreAuthorize(value = "hasRole('ROLE_ADMIN')") 
@RequestMapping(value = "https://stackoverflow.com/users/employee") 
public Page<User> listEmployees(Pageable pageable) { 
    return usersRepository.findEmployeeUsers(pageable); 
} 

Gibt es eine Möglichkeit, projection für findEmployeeUsers Methode anzugeben, wenn es direkt wie oben aufgerufen wird?

Ich weiß, dass der obige Code für jemanden seltsam aussehen könnte ... es wäre möglich, das Repository über REST verfügbar zu machen und die @PreAuthorize Sache in das Repository zu legen. Thought Controller ist der richtige Ort für Sicherheitsüberprüfungen - es ist natürlicher und einfacher zu testen.

Also, kann projection Ding irgendwie in eine Repository-Methode direkt aufgerufen werden?

Antwort

36

Nein, das ist es nicht, zumal Projektionen normalerweise von Fall zu Fall auf das Ergebnis einer Abfrageausführung angewendet werden. Daher sind sie derzeit so konzipiert, dass sie selektiv auf Domain-Typen angewendet werden können.

Ab der neuesten Spring Data Fowler Freigabe Zug GA-Version kann die Projektionsinfrastruktur programmgesteuert in Spring MVC-Steuerungen verwendet werden. erklären Sie einfach eine Spring-Bean für SpelAwareProxyProjectionFactory:

@Configuration 
class SomeConfig { 

    @Bean 
    public SpelAwareProxyProjectionFactory projectionFactory() { 
    return new SpelAwareProxyProjectionFactory(); 
    } 
} 

Dann injizieren es in Ihrem Controller und verwenden es:

@Controller 
class SampleController { 

    private final ProjectionFactory projectionFactory; 

    @Autowired 
    public SampleController(ProjectionFactory projectionFactory) { 
    this.projectionFactory = projectionFactory; 
    } 

    @PreAuthorize(value = "hasRole('ROLE_ADMIN')") 
    @RequestMapping(value = "https://stackoverflow.com/users/employee") 
    public Page<?> listEmployees(Pageable pageable) { 

    return usersRepository.findEmployeeUsers(pageable).// 
     map(user -> projectionFactory.createProjection(Projection.class, user); 
    } 
} 

Sehen Sie, wie wie von der neuesten Version Page eine map(…) Methode, die verwendet werden können, zu transformieren der Seiteninhalt im laufenden Betrieb. Wir verwenden ein JDK 8 Lambda, um einen Umwandlungsschritt unter Verwendung der ProjectionFactory bereitzustellen.

+0

Danke, das sieht nach einem anständigen Ansatz aus! Leider kann ich es nicht testen, da ich mit SpringBoot 1.2.2 (3) gesperrt bin - es hat nicht die laters GA-Version von spring-data project ... mir ist klar, dass das eine Frage anderer Frage ist - aber ist Gibt es einen Weg, die GA in eine SpringBoot 1.2.2 oder 1.2.3 App zu stecken, um das Ding zu testen? – Barbadoss

+1

Hier ist, wie das gemacht werden kann - http://spring.io/blog/2015/03/26/what-s-new-in-spring-data-fowler, versuchen und ausprobieren die neue Projektionen Infrastruktur. – Barbadoss

+0

@OliverGierke es scheint, dass dies nicht mehr in der aktuellen Version von Spring Data funktioniert? Mit dem angegebenen Beispiel löst Jackson eine "com.fasterxml.jackson.core.JsonGenerationException aus: Ein Objekt kann nicht gestartet werden, Feldname wird erwartet" –

Verwandte Themen