Entité JPA sans id

, j'ai une base de données avec la structure suivante:

CREATE TABLE entity (
    id SERIAL,
    name VARCHAR(255),
    PRIMARY KEY (id)
);

CREATE TABLE entity_property (
    entity_id SERIAL,
    name VARCHAR(255),
    value TEXT
);

Lorsque j'essaie de créer une classe EntityProperty

@Entity
@Table(name="entity_property")
public class EntityProperty {

    private String name;
    private String value;

    @Column(name="name")
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    @Column(name="value", nullable=true, length=255)
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
}

Je reçois l'exception suivante:

org.hibernate.AnnotationException: No identifier specified for entity: package.EntityProperty

Je sais que les entités JPA doivent avoir une clé primaire mais je ne peux pas changer le schéma de base de données pour des raisons indépendantes de ma volonté. Est-il possible de créer des entités JPA (Hibernate) qui fonctionneront avec le schéma de base de données comme ceci?

37
demandé sur lloiacono 2010-09-29 14:53:36

5 réponses

Je suppose que votre entity_property est une clé composite (entity_id, name)entity_id est une clé étrangère vers entity. Si c'est le cas, vous pouvez le Mapper comme suit:

@Embeddable
public class EntityPropertyPK {
    @Column(name = "name")
    private String name;

    @ManyToOne
    @JoinColumn(name = "entity_id")
    private Entity entity;

    ...
}

@Entity 
@Table(name="entity_property") 
public class EntityProperty { 
    @EmbeddedId
    private EntityPropertyPK id;

    @Column(name = "value")
    private String value; 

    ...
}
36
répondu axtavt 2017-12-21 15:20:00

Je sais que les entités JPA doivent avoir une clé primaire mais je ne peux pas changer la structure de la base de données pour des raisons indépendantes de ma volonté.

Plus précisément, une entité JPA doit avoir Id défini. Mais un JPA Id ne doit pas nécessairement être mappé sur la clé primaire de la table (et JPA peut en quelque sorte traiter une table sans clé primaire ou contrainte unique).

Est-il possible de créer des entités JPA (Hibernate) qui fonctionneront avec la structure de base de données comme ceci?

Si vous avez une colonne ou un ensemble de colonnes dans la table qui rend une unique valeur, vous pouvez utiliser cet ensemble unique de colonnes que votre Id en JPA.

Si votre table n'a pas de colonnes uniques, vous pouvez utiliser toutes les colonnes comme Id.

Et si votre table a un identifiant mais que votre entité ne le fait pas, faites-en un Embeddable.

24
répondu Pascal Thivent 2010-09-29 16:16:29

Voir Java Persistence livre: Identité et le Séquençage

La partie pertinente de votre question Est la section No Primary Key :

Parfois, votre objet ou votre table n'a pas de clé primaire. La meilleure solution dans ce cas est normalement d'ajouter un id généré à l'objet et table. Si vous n'avez pas cette option, il y a parfois une colonne ou ensemble de colonnes dans la table qui constituent une valeur unique. Vous pouvez utiliser cet ensemble unique de colonnes comme identifiant dans JPA. Le JPA Id ne doit pas toujours correspondre à la clé primaire de la table de base de données une clé primaire ou une contrainte unique n'est pas requise.

Si votre table n'a vraiment pas de colonnes uniques, Utilisez toutes les colonnes comme l'id. Généralement, lorsque cela se produit, les données sont en lecture seule, donc même si la table permet de dupliquer des lignes avec les mêmes valeurs, les objets sera le même de toute façon, donc peu importe que JPA pense qu'ils sont le même objet. Le problème avec l'autorisation des mises à jour et des suppressions est qu'il n'y a aucun moyen d'identifier de manière unique la ligne de l'objet, donc tout les lignes correspondantes seront mises à jour ou supprimées.

Si votre objet n'a pas d'id, mais que sa table le fait, c'est bien. Faire de l'objet un objet Embeddable, objets intégrables n'avez pas les identifiants. Vous aurez besoin d'un Entity qui contient ceci Embeddable pour persister et l'interroger.

15
répondu Gilberto 2015-12-18 17:12:42

Je suppose que vous pouvez utiliser @CollectionOfElements (pour hibernate/jpa 1) / @ElementCollection (jpa 2) à la carte une collection de "propriétés d'entité" à un List dans entity.

Vous pouvez créer le type EntityProperty et l'annoter avec @Embeddable

3
répondu Bozho 2010-09-29 10:58:56

S'il existe une association entre l'entité et entity_property vous pouvez utiliser entity_id comme identificateur.

1
répondu Qwerky 2010-09-29 10:59:19