web-dev-qa-db-fra.com

@NamedNativeQuery avec @SqlResultSetMapping pour les non-entités

J'ai utilisé ceci post comme exemple. J'ai une requête de jointure complexe (simplifiée ici). Il renvoie un sous-ensemble de valeurs de deux tables (et une colonne dérivée utilisant CASE). Je ne pense pas avoir besoin d'utiliser une annotation d'entité car l'objet renvoyé de mon jeu de résultats n'est pas une table réelle dans mon schéma.

Mon objet non-entité que je souhaite conserver résulte de ma requête de jointure:

@SqlResultSetMapping(
           name="myMapping",
           classes={
              @ConstructorResult(
                   targetClass=CarLimitDelta.class,
                     columns={
                        @ColumnResult(name="caseCol"),
                        @ColumnResult(name="colA"),
                        @ColumnResult(name="colB"),
                        }
              )
           }
)
@NamedNativeQuery(name="CarLimitDelta.getCarLimitDelta", 
        resultSetMapping="myMapping", 
        query="SELECT CASE "+ 
           "WHEN t.foo IS NULL THEN 'INS' "+
           "WHEN s.foo IS NULL THEN 'DEL' "+
           "ELSE 'UPD' "+
        "END caseCol "+
     ", T.bar colA "+
     ", S.bar ColB "+
     "FROM tableA S "+
     "FULL JOIN TableB ON S.bar= T.bar")

public class CarLimitDelta {
        private String caseCol;
        private String colA;
        private String colB;


    //getters/setters/etc
    }

Mon repo:

@Repository
public interface CarLimitRepository extends CrudRepository<CarLimitDelta, String> {
    List<CarLimitDelta> getCarLimitDelta();
}

mon service:

@Service
public class CarLimitService {

    @Autowired
    CarLimitRepository carLimitRepository ;

    public void deleteAll() {
        carLimitRepository.deleteAll();
    }

    public List<CarLimitDelta> getCarLimitDelta() {
        return carLimitRepository.getCarLimitDelta();
    }


}

Je ne sais pas comment obtenir mon référentiel pour voir ma nouvelle méthode de requête native CarLimitDelta.getCarLimitDelta définie dans ma NamedNativeQuery. J'obtiens l'erreur suivante:

Requête dérivée non valide! Aucune propriété getCarLimitDelta trouvée pour le type CarLimitDelta!

10
Micho Rizo

Le @SqlResultSetMapping et @NamedNativeQuery les annotations doivent être sur un @Entity, pas sur le POJO non-entité.

Si l'entité est Foo, ajoutez les annotations comme suit:

@SqlResultSetMapping(
           name="myMapping",
           classes={
              @ConstructorResult(
                   targetClass=CarLimitDelta.class,
                     columns={
                        @ColumnResult(name="caseCol"),
                        @ColumnResult(name="colA"),
                        @ColumnResult(name="colB"),
                        }
              )
           }
)
@NamedNativeQuery(name="Foo.getCarLimitDelta", 
        resultSetMapping="myMapping", 
        query="...")
@Entity
public class Foo {
  ...
}

Notez que le @NamedNativeQuery le nom est précédé du nom de l'entité, par exemple Foo.getCarLimitDelta.

Ajoutez ensuite la méthode au référentiel Foo:

@Repository
public interface FooRepository extends CrudRepository<Foo, String> {
    List<CarLimitDelta> getCarLimitDelta();
}

Notez que le nom de la méthode, getCarLimitDelta, correspond à @NamedNativeQuery nom, moins le préfixe.

14
codemonkey