JPA Native Query select et cast object

j'ai un Objet Admin qui s'étend User. Par défaut les deux objets sont dans la table User_ de ma base de données Derby (champs inclus De ). Normalement je choisirais un User comme ceci:

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<User> query = cb.createQuery(User.class);
Root user= query.from(User.class);
Predicate predicateId = cb.equal(category.get("id"), id);
query.select(user).where(predicateId);
return em.createQuery(query).getSingleResult();

Cependant en raison de la complexité de ma requête j'utilise une requête native comme celle-ci:

Query query = em.createNativeQuery("SELECT USER.* FROM USER_ AS USER WHERE ID = ?");
query.setParameter(1, id);
return (User) query.getSingleResult();

bien que cela jette une exception cast. Je suppose que c'est dû à n'importe quel champ de Admin.

Ma question est, comment puis-je sélectionner un User utiliser une requête native avec un résultat égal comme premier exemple (incluant les mêmes valeurs pour @LOB et @ManyToOne (et cetera) comme la requête JPQL retournerait)?

18
demandé sur Menno 2013-07-17 23:50:01

3 réponses

Vous pouvez essayer l'une des manières suivantes:

  • en utilisant la méthode createNativeQuery(sqlString, resultClass)

    les requêtes natives peuvent aussi être définies dynamiquement en utilisant le EntityManager.createNativeQuery() API.

    String sql = "SELECT USER.* FROM USER_ AS USER WHERE ID = ?";
    
    Query query = em.createNativeQuery(sql, User.class);
    query.setParameter(1, id);
    User user = (User) query.getSingleResult();
    
  • en utilisant l'annotation @NamedNativeQuery

    les requêtes natives sont définies par @NamedNativeQuery et @NamedNativeQueries les annotations, ou <named-native-query> élément XML.

    @NamedNativeQuery(
        name="complexQuery",
        query="SELECT USER.* FROM USER_ AS USER WHERE ID = ?",
        resultClass=User.class
    )
    public class User { ... }
    
    Query query = em.createNamedQuery("complexQuery", User.class);
    query.setParameter(1, id);
    User user = (User) query.getSingleResult();
    

Vous pouvez lire plus dans l'excellent livre ouvert Java Persistence (disponible dans PDF).

───────

NOTE: en ce qui concerne l'utilisation de getSingleResult() pourquoi ne jamais utiliser getSingleResult() in JPA.

42
répondu Paul Vargas 2017-05-21 23:29:31

consultez JPA: comment convertir un résultat de requête natif en collection de classe POJO

Postgres 9.4,

List<String> list = em.createNativeQuery("select cast(row_to_json(u) as text) from myschema.USER_ u WHERE ID = ?")
                   .setParameter(1, id).getResultList();

User map = new ObjectMapper().readValue(list.get(0), User.class);
1
répondu Darshan Patel 2017-11-11 05:41:38

tout d'abord créer un POJO modèle

import javax.persistence.*;
@Entity
@Table(name = "sys_std_user")
public class StdUser {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "class_id")
    public int classId;
    @Column(name = "user_name")
    public String userName;
    //getter,setter
}

Controller

import com.example.demo.models.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;
import java.util.List;

@RestController
public class HomeController {
    @PersistenceUnit
    private EntityManagerFactory emf;

    @GetMapping("/")
    public List<StdUser> actionIndex() {
        EntityManager em = emf.createEntityManager(); // Without parameter
        List<StdUser> arr_cust = (List<StdUser>)em
                .createQuery("SELECT c FROM StdUser c")
                .getResultList();
        return arr_cust;
    }

    @GetMapping("/paramter")
    public List actionJoin() {
        int id = 3;
        String userName = "Suresh Shrestha";
        EntityManager em = emf.createEntityManager(); // With parameter
        List arr_cust = em
                .createQuery("SELECT c FROM StdUser c WHERE c.classId = :Id ANd c.userName = :UserName")
                .setParameter("Id",id)
                .setParameter("UserName",userName)
                .getResultList();
        return arr_cust;
    }
}
0
répondu Ram Pukar 2017-11-10 13:14:11