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)?
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.
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);
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;
}
}