2015-03-16 4 views
22

ich ein Spring Data Repository-Methode mit einer nativen AbfrageSpring Data JPA Karte das Ergebnis auf Non-Entity POJO

@Query(value = "SELECT g.*, gm.* FROM group g LEFT JOIN group_members gm ON g.group_id = gm.group_id and gm.user_id = :userId WHERE g.group_id = :groupId", nativeQuery = true) 
    GroupDetails getGroupDetails(@Param("userId") Integer userId, @Param("groupId") Integer groupId); 

und ich möchte zur Karte das Ergebnis zu Non-Entity POJO GroupDetails haben.

Ist es möglich und wenn ja, könnten Sie bitte ein Beispiel geben?

+0

ein Kommentar zur Lösung? – Daimon

Antwort

30

Unter der Annahme, GroupDetails wie in ORID Antwort haben Sie JPA versucht 2.1 @ConstructorResult?

@SqlResultSetMapping(
    name="groupDetailsMapping", 
    classes={ 
     @ConstructorResult(
      targetClass=GroupDetails.class, 
      columns={ 
       @ColumnResult(name="GROUP_ID"), 
       @ColumnResult(name="USER_ID") 
      } 
     ) 
    } 
) 

@NamedNativeQuery(name="getGroupDetails", query="SELECT g.*, gm.* FROM group g LEFT JOIN group_members gm ON g.group_id = gm.group_id and gm.user_id = :userId WHERE g.group_id = :groupId", resultSetMapping="groupDetailsMapping") 

und Verwendung in Repository-Schnittstelle folgende:

GroupDetails getGroupDetails(@Param("userId") Integer userId, @Param("groupId") Integer groupId); 

Nach Spring Data JPA documentation, Frühling wird zunächst versuchen, benannte Abfrage für Ihre Methodennamen zu finden - so von @NamedNativeQuery verwenden, @SqlResultSetMapping und @ConstructorResult Sie sollte in der Lage sein, dieses Verhalten zu erreichen

+8

Damit Spring-Daten mit NamedNativeQuery übereinstimmen können, muss der Klassenname der Domänenentität, gefolgt von einem Punkt, dem Namen der NamedNativeQuery vorangestellt werden. Daher sollte der Name (unter der Annahme, dass die Domänenentität eine Gruppe ist) 'Group.getGroupDetails' sein. –

+0

@GrantLay können Sie sich diese Frage ansehen: https://Stackoverflow.com/q/44871757/7491770 Ich habe genau diese Art von Problem. – ram

+0

Wie gebe ich eine Liste solcher Objekte zurück? –

2

Wenn GroupDetails ist so etwas wie:

public class GroupDetails { 

    int groupId; 
    int userId; 

    public GroupDetails(int groupId , int userId) { 
     this.groupId = groupId; 
     this.userId = userId; 
    } 

    // getters setters, etc. 
} 

Folgende Arbeiten sollten:

@Query(value = "SELECT new GroupDetails(gm.group_id, gm.user_id) FROM group g LEFT JOIN group_members gm ON g.group_id = gm.group_id and gm.user_id = :userId WHERE g.group_id = :groupId")

+3

funktioniert nicht mit org.hibernate.exception.SQLGrammarException: konnte ResultSet nicht extrahieren. Vielleicht im Fall von nativeQuery = true? – alexanoid

+4

Sie haben Recht. Native Abfragen können nicht mit 'select new (...)' verwendet werden. Sie müssen Ihre Abfrage in 'HQL' ändern. –

+0

Abhängig von Ihrem Mapping wird es so etwas wie:' Wählen Sie neue GroupDetails (gm.groupId, gm.userId) aus der Gruppe als g links verbinden g.groupMembers als gm wo g. groupId =: groupId und gm.userId =: userId' –

0

Sie können etwas wie

tun

Und es muss Constructor wie

public IssuesDto(long id, String department, String issueName, String issueCategory, String issueDescriptor, 
      String description) { 
     super(); 
     this.id = id; 
     this.department = department; 
     this.issueName = issueName; 
     this.issueCategory = issueCategory; 
     this.issueDescriptor = issueDescriptor; 
     this.description = description; 
    } 
+3

Die Frage ist über native Abfragen, nicht in HQL geschriebene Abfragen. – DBK

4

ich sein denke, der einfachste Weg, dies zu tun ist, so genannte Projektion zu verwenden. Es kann Abfrageergebnisse Schnittstellen zuordnen. Die Verwendung von SqlResultSetMapping ist inconvienient und macht Ihren Code hässlich :).

Ein Beispiel direkt aus Federdaten JPA-Quellcode:

public interface UserRepository extends JpaRepository<User, Integer> { 

@Query(value = "SELECT firstname, lastname FROM SD_User WHERE id = ?1", nativeQuery = true) 
NameOnly findByNativeQuery(Integer id); 

static interface NameOnly { 

    String getFirstname(); 

    String getLastname(); 
} 

Sie können auch diese Methode verwenden, um eine Liste von Ansichten zu erhalten.

Verwandte Themen