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?

31
demandé sur ROMANIA_engineer 2009-05-29 16:54:06

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

25
répondu Edward Q. Bridges 2009-05-29 13:04:50

Pour chaque entité, vous devez désigner au moins un des éléments suivants:

  • un @Id
  • multiple @Id et an @IdClass (pour une clé primaire composite)
  • @EmbeddedId

alors peut-être que vous pouvez créer une clé primaire composite, contenant plusieurs champs?

6
répondu Fortega 2009-05-29 13:03:30

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.

}
3
répondu luke 2017-05-18 14:13:34

voici un exemple qui a 2 clés comme" Id "clés: https://gist.github.com/3796379

1
répondu rogerdpack 2012-09-27 20:46:34

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.

0
répondu rudolfson 2009-05-29 13:01:26

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.

-1
répondu Stacy Mobley 2016-04-06 22:39:26