2009-03-13 4 views
27

J'utilise actuellement Eclipselink, mais je sais que maintenant, la plupart des implémentations JPA ont été assez standardisées. Existe-t-il une méthode native pour mapper une entité JPA à une vue? Je ne cherche pas à insérer/mettre à jour, mais la question est vraiment comment gérer l'annotation @Id. Chaque entité dans le monde JPA doit avoir un champ ID, mais la plupart des vues que j'ai créées ne sont pas conformes à cela. Y a-t-il un support natif pour cela dans l'APP ou ai-je besoin d'utiliser des hacks pour le faire fonctionner? J'ai beaucoup cherché et trouvé très peu d'informations à propos de cela.JPA prend-il en charge le mappage sur les vues sql?

+0

Vues fonctionne comme des tables normales, si vous vues ne correspond pas bien avec la cartographie JPA ORM vous pouvez utiliser à la place une procédure stockée pour renvoyer un curseur personnalisé formé à partir de la vue (s). Vous pouvez mapper des procédures stockées dans EclipseLink à l'aide de l'annotation @NamedStoredProcedureQuery. Pour plus d'informations sur ce Google pour "Extensions EclipseLink". –

Répondre

7

Tout en utilisant l'annotation @Id avec des champs de types ne sont pas la seule façon de préciser l'identité d'une entité directement pris en charge (voir @IdClass avec plusieurs @Id annotations ou @EmbeddedId avec @Embedded), la spécification JPA nécessite 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 n'est pas différent du mappage vers une table d'un point de vue SQL, vous pouvez toujours utiliser des requêtes natives (createNativeQuery sur EntityManager) pour récupérer des valeurs scalaires à la place.

0

J'ai regardé ceci moi-même, et j'ai trouvé un bidouillage que je ne suis pas 100% certains travaux mais cela semble prometteur.

Dans mon cas, j'ai une colonne FK dans la vue qui peut effectivement fonctionner comme un PK - une instance donnée de cet objet étranger ne peut apparaître qu'une seule fois dans la vue. J'ai défini deux objets hors de ce champ: l'un est désigné par l'ID et représente la valeur brute du champ, et l'autre est désigné 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% celui-ci (et je vais supprimer cette réponse si elle se révèle ne pas travailler), mais il a obtenu mon code passé un point de chute particulier.

Ce n'est pas le cas si cela s'applique à votre situation spécifique. Et il y a une excellente chance qu'après 11 mois, vous ne vous en souciez plus. :-) Que diable, ce badge "Necromancer" ne se gagne pas tout seul ...

0

A mon avis, j'ai un identifiant "unique", donc je l'ai mappé comme l'ID Entité. Il 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; 
Questions connexes