Hibernation / persistance sans @Id
j'ai une vue de la base de données qui fournit un ensemble de résultats qui n'a pas de vraie clé primaire. Je veux utiliser Hibernate / Persistence pour mapper ce résultat sur les objets Java. Bien sûr, parce qu'il n'y a pas de PK, Je ne peux pas décorer n'importe quel champ avec @Id
.
lors de son déploiement, Hibernate se plaint de la disparition du @Id
. Comment je peux contourner ça?
6 réponses
S'il y a une combinaison de colonnes qui rend une rangée unique, modéliser une classe de clés primaires autour de la combinaison de colonnes. S'il n'y en a pas, vous n'avez pas de chance, mais vous devriez réexaminer le design de la vue, car cela n'a probablement pas de sens.
Il ya un couple de différentes approches:
@Entity
public class RegionalArticle implements Serializable {
@Id
public RegionalArticlePk getPk() { ... }
}
@Embeddable
public class RegionalArticlePk implements Serializable { ... }
ou:
@Entity
public class RegionalArticle implements Serializable {
@EmbeddedId
public RegionalArticlePk getPk() { ... }
}
public class RegionalArticlePk implements Serializable { ... }
les détails sont ici: http://docs.jboss.org/ejb3/app-server/HibernateAnnotations/reference/en/html_single/index.html#d0e1517
Voici une annonce qui décrit une question similaire: http://www.theserverside.com/discussions/thread.tss?thread_id=22638
au lieu de chercher des solutions de rechange dans Hibernate, il pourrait être plus facile d'ajouter l'id fictif dans votre vue de base de données. Supposons que nous avons une vue PostgreSQL avec deux colonnes et aucune d'elles n'est unique (et il n'y a pas de clé primaire car Postgres ne permet pas de faire PK ou toute autre contrainte sur les vues) ex.
| employee_id | project_name |
|:------------|:-------------|
| 1 | Stack01 |
| 1 | Jira01 |
| 1 | Github01 |
| 2 | Stack01 |
| 2 | Jira01 |
| 3 | Jira01 |
------------------------------
Qui est représenté par la requête suivante:
CREATE OR REPLACE VIEW someschema.vw_emp_proj_his AS
SELECT DISTINCT e.employee_id,
pinf.project_name
FROM someschema.project_info pinf
JOIN someschema.project_employee pe ON pe.proj_id = pinf.proj_id
JOIN someschema.employees e ON e.employee_id = pe.emloyee_id
on peut ajouter dummy id en utilisant row_number ():
SELECT row_number() OVER (ORDER BY subquery.employee_id) AS row_id
comme dans cet exemple:
CREATE OR REPLACE VIEW someschema.vw_emp_proj_his AS
SELECT row_number() OVER (ORDER BY subquery.employee_id) AS row_id,
subquery.employee_id,
subquery.project_name
FROM
(SELECT DISTINCT e.employee_id,
pinf.project_name
FROM someschema.project_info pinf
JOIN someschema.project_employee pe ON pe.proj_id = pinf.proj_id
JOIN someschema.employees e ON e.employee_id = pe.emloyee_id ) subquery;
et la table ressemblera à ceci:
| row_id | employee_id | project_name |
|:------------|:------------|:-------------|
| 1 | 1 | Stack01 |
| 2 | 1 | Jira01 |
| 3 | 1 | Github01 |
| 4 | 2 | Stack01 |
| 5 | 2 | Jira01 |
| 6 | 3 | Jira01 |
-------------------------------------------
maintenant nous pouvons utiliser row_id as @Id dans les données JPA/Hibernate/Spring:
@Id
@Column(name = "row_id")
private Integer id;
comme dans l'exemple:
@Entity
@Table(schema = "someschema", name = "vw_emp_proj_his")
public class EmployeeProjectHistory {
@Id
@Column(name = "row_id")
private Integer id;
@Column(name = "employee_id")
private Integer employeeId;
@Column(name = "project_name")
private String projectName;
//Getters, setters etc.
}
voici un exemple qui a 2 clés comme" Id "clés: https://gist.github.com/3796379
vous pouvez vérifier s'il y a une identification logique et fournir des informations cartographiques en conséquence. Hibernate ne vérifiera pas l'existence d'une clé primaire définie dans la base de données.
bien que ce ne soit pas exactement ce que vous demandez, voici un petit truc que j'utilise. Demandez à la requête de sélectionner " rownum "et de définir" rownum " comme votre colonne ID dans le modèle. Cela rendra chaque rang unique pour hiberner.