Spring Data JPA Projection des champs sélectionnés dans la DB

J'ai été le tester Printemps de Données 1.10.4.La LIBÉRATION, à la suite de l'exemple au Printemps de Données Docs http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections

et j'ai remarqué quelques problèmes pour lesquels j'ai 2 questions.

Première supposons que j'ai ces 2 entités:

@Entity
public class Person {

  @Id @GeneratedValue
  private Long id;
  private String firstName, lastName;

  @OneToOne
  private Address address;
}

@Entity
public class Address {

  @Id @GeneratedValue
  private Long id;
  private String street, state, country;
}
  • Question 1:

pour la suite des projections:

interface PersonLimited {  

  String getFirstName(); 

  AddressLimited getAddress();
}

interface AddressLimited {  

  String getCountry(); 
}

quand je lance findPersonByFirstNameProjectedForlimiteddata

interface PersonRepository extends CrudRepository<Person, Long> {

  @Query("select p from Person p where p.firstName = ?1")
  PersonLimited findPersonByFirstNameProjectedForLimitedData(String firstName);
}

il retourne exactement ce qu'attend :

{
    firstName: 'Homer',
    address: {
        country: 'USA'
    }
}

maintenant, si je regarde dans le SQL généré, c'est ce que j'ai:

SELECT person0_.firstName      AS col_0_0_, 
       address1_.id            AS id1_13_, 
       address1_.street        AS street2_13_, 
       address1_.state         AS state3_13_, 
       address1_.country       AS country4_13_
FROM   person person0_ 
       LEFT OUTER JOIN address address1_ 
                    ON person0_.addressId = address1_.id 
WHERE  person0_.firstName = ?  

La projection de la "Personne" de l'entité est de sélectionner uniquement "fistName", ce qui est correct à 100% parce que dans le PersonLimited interface, je ne l'ai défini "getFirstName".

Mais pour l ' "Adresse" de l'entité, il sélectionne tous les champs, ce qui est faux parce que dans le AddressLimited interface, je ne l'ai défini "getCountry", Il convient de sélectionner uniquement "pays".

La requête générée doit être quelque chose comme:

SELECT person0_.firstName      AS col_0_0_, 
       address1_.country       AS country4_13_
FROM   person person0_ 
       LEFT OUTER JOIN address address1_ 
                    ON person0_.addressId = address1_.id 
WHERE  person0_.firstName = ?  

donc la question est, pourquoi il n'est pas en sélectionnant uniquement le champ "pays" à l'Adresse "entité"? pourquoi il a besoin pour sélectionner tous les champs? est-ce un bug au Printemps?

  • Question 2:

pour la même projection que ci-dessus,

quand je lance findAllPersonsProjectedForLimiteddata

interface PersonRepository extends CrudRepository<Person, Long> {

  @Query("select p from Person p")
  List<PersonLimited> findAllPersonsProjectedForLimitedData();
}

il retourne exactement ce qu'attend :

[
     {
        firstName: 'Homer',
        address: {
            country: 'USA'
        }
     },
     {
        firstName: 'Maggie',
        address: {
            country: 'USA'
        }
     }
]

maintenant, si je regarde dans le SQL généré, c'est ce que j'ai:

SELECT person0_.id                 AS id1_18_, 
       person0_.firstName          AS firstName2_18_, 
       person0_.lastName           AS lastName3_18_, 
       person0_.addressid          AS company4_18_
FROM   person person0_ 

SELECT address0_.id         AS id1_13_0_, 
       address0_.street     AS street2_13_0_, 
       address0_.state      AS state3_13_0_, 
       address0_.country    AS country4_13_0_
FROM   address address0_ 
WHERE  address0_.id = ? 

ici, la projection pour la Personne et l'Adresse des entités à sélectionner tous les champs qui est faux, il convient de sélectionner uniquement "prénom" et "pays".

La requête générée doit être quelque chose comme:

SELECT person0_.firstName        AS firstName2_18_
FROM   person person0_ 

SELECT address0_.country    AS country4_13_0_
FROM   address address0_ 
WHERE  address0_.id = ? 

est-ce le comportement normal de ne pas sélectionner uniquement les champs dont nous avons besoin?

Merci,

Je ne comprends pas vos questions: c'est de choisir exactement ce dont il a besoin.
J'ai édité mes questions. le truc, c'est lors de l'utilisation de "Fermé Projection", comme celui que j'utilise, JPA doit uniquement sélectionner les champs que j'ai défini dans ma Projection des "interfaces". c'est ce que le Printemps de Données Doc a dit: Fermé projections exposer un sous-ensemble de propriétés par conséquent, ils peuvent être utilisés pour optimiser la requête de manière à réduire les champs sélectionnés dans la banque de données
ok, maintenant je comprends votre question. Très intéressante.
Je voudrais aller avec la manière standard od de projections sens "SÉLECTIONNEZ nouveau com.de l'entreprise.YourDto(p.prénom, p.adresse.pays) DE la Personne p". Il vous offre plus de possibilités dans votre DTO que dans cette approche de l'interface.
2 ans après et personne ne répond 🙁

OriginalL'auteur arammal | 2016-10-22