2017-04-11 77 views
2

我想使用Spring JPA的投影從查詢結果中篩選出不必要的數據。但是,我有多個預測需要在相同的接口方法上使用。Spring JPA:在同一查詢接口上使用多個投影

問題是,我試圖用不同的返回對象從同一個方法中查詢數據,但java不允許這樣做。

該查詢是由JPA根據方法名稱自動生成的,因此我無法更改方法名稱。

是否有替代方案,比創建一個新的接口等,因爲我認爲這是一個麻煩和不必要的

這裏是一個示例代碼,我試圖做的。

Auto-Generated Query

public interface UserRepository extends CrudRepository<UserAccount, Long> { 

    AuthenticateProjection getByUsername(String username); 

    UserDetailsProjection getByUsername(String username); 

} 

Projections

public interface AuthenticateProjection { 

    @Value("#{target.username}") 
    String getUsername(); 

    @Value("#{target.credentail.token}") 
    String getHashPassword(); 
} 

public interface UserDetailsProjection { 

    @Value("#{target.username}") 
    String getUsername(); 

    @Value("#{target.firstname}") 
    String getFirstName(); 

    @Value("#{target.lastname}") 
    String getLastName(); 
} 
+0

調用查詢方法 - 這是從控制器返回,或內部使用? – chrylis

+0

@chrylis它將返回到控制器 – XPLOT1ON

回答

2

所以我設法弄清楚如何使用多個投影使用單個查詢。

<T> T getByUsername(String username, Class<T> projection) 

這允許方法調用方指定要應用於查詢的投影類型。

爲了進一步改善這個,所以不太容易出錯,我做了一個空白的接口,爲了能夠將類插入到參數中,投影將不得不擴展。

public interface JPAProjection { 
} 

public interface UserRepository extends CrudRepository<UserAccount, Long> { 
    <T extends JPAProjection > T getByUsername(String username, Class<? extends JPAProjection> projection); 
} 

Projection Interface

public interface UserDetailsProjection extends JPAProjection{ 
    @Value("#{target.username}") 
    String getUsername(); 

    @Value("#{target.firstname}") 
    String getFirstname(); 

    @Value("#{target.lastname}") 
    String getLastname(); 
} 

然後,我可以問:你爲什麼要「過濾器」的信息,通過

getByUsername("...", UserDetailsProjection.class) 
+0

我試圖使用相同的解決方案,但它不適用於我。在Eclipse控制檯中,我看到一個錯誤:'由...引起:org.hibernate.hql.internal.ast.QuerySyntaxException:意外的令牌:從第1行第9列[從com.app.company.domain.organization.Organization中選擇generatedAlias0 where generatedAlias0.deletedAt is null]'。看看「select」語句:沒有任何列。也許你有同樣的問題?看來版本庫沒有收到正確的投影類型.....任何想法?非常感謝! –

+0

嗯這很奇怪。我沒有任何問題。你介意附上你的impl嗎? Pastebin可能? @AndreaBevilacqua – XPLOT1ON