web-dev-qa-db-fra.com

JPA prend-il en charge le mappage vers les vues SQL?

J'utilise actuellement Eclipselink, mais je sais maintenant que la plupart des implémentations de JPA ont été assez standardisées. Existe-t-il un moyen natif de mapper une entité JPA sur une vue? Je ne cherche pas à insérer/mettre à jour, mais la question est vraiment de savoir comment gérer l'annotation @Id. Chaque entité du monde JPA doit avoir un champ ID, mais bon nombre des vues que j'ai créées ne s'y conforment pas. Existe-t-il un support natif pour cela dans le JPA ou dois-je utiliser des hacks pour que cela fonctionne? J'ai beaucoup cherché et trouvé très peu d'informations à ce sujet.

31
GBa

L'utilisation de l'annotation @Id avec des champs de types directement pris en charge n'est pas le seul moyen de spécifier l'identité d'une entité (voir @IdClass avec plusieurs annotations @Id ou @EmbeddedId avec @Embedded), la spécification JPA requiert une clé primaire pour chaque entité.

Cela dit, vous n'avez pas besoin d'entités pour utiliser JPA avec des vues de base de données. Comme le mappage vers une vue ne diffère pas du mappage vers une table du point de vue SQL, vous pouvez toujours utiliser des requêtes natives (createNativeQuery sur EntityManager) pour récupérer des valeurs scalaires.

8
Nils Wloka

J'ai moi-même étudié cette question et j'ai trouvé que je ne suis pas sûr à 100% que cela fonctionne, mais cela semble prometteur.

Dans mon cas, la vue contient une colonne FK qui peut effectivement fonctionner en tant que PK. Toute instance donnée de cet objet étranger ne peut apparaître qu'une seule fois dans la vue. J'ai défini deux objets à partir de ce premier champ: l'un est désigné ID et représente la valeur brute du champ et l'autre est en lecture seule et représente l'objet auquel il est fait référence.


@Id
@Column(name = "foreignid", unique = true, nullable = false)
public Long getForeignId() {
...

@OneToOne
@JoinColumn(name = "foreignid", insertable=false, updatable=false)
public ForeignObject getForeignObject() {
...

Comme je l'ai dit, je ne suis pas sûr à 100% de celui-ci (et je vais simplement supprimer cette réponse s'il s'avère que cela ne fonctionne pas), mais mon code a dépassé un point de blocage particulier.

Ne sais pas si cela s'applique à votre situation spécifique, cependant. Et il y a une excellente chance qu'après 11 mois, vous ne vous en souciez plus. :-) C'est quoi ce badge "Nécromancien" qui ne gagne pas tout seul ...

0
BlairHippo

A mon avis, j'ai un identifiant "unique", je l'ai donc mappé comme identifiant d'entité. Cela fonctionne très bien:

@Entity
@Table(name="table")
@NamedQuery(name="Table.findAll", query="SELECT n FROM Table n")
public class Table implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name="column_a")
    private int columnA;
0
Everton Mendonça