Hibernate lève org.hibernate.AnnotationException: aucun identifiant spécifié pour l'entité: com..domain.idea.MAE_MFEView

207

Pourquoi ai-je cette exception?

package com.domain.idea;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import org.hibernate.annotations.AccessType;

/**
 * object model for the view [InvestmentReturn].[vMAE_MFE]
 */
@Entity
@Table(name="vMAE_MFE", schema="InvestmentReturn")
@AccessType("field")
public class MAE_MFEView
{
    /**
     * trade property is a SuggestdTradeRecommendation object
     */
    @OneToOne(fetch = FetchType.LAZY , cascade = { CascadeType.PERSIST })
    @JoinColumn(name = "suggestedTradeRecommendationID")
    private SuggestedTradeRecommendation trade;

    /**
     * Most Adeverse Excursion value
     */
    private int MAE;

    public int getMAE()
    {
        return MAE;
    }

    /**
     * Most Favorable Excursion value
     */
    private int MFE;

    public int getMFE()
    {
        return MFE;
    }

    /**
     * @return trade property
     * see #trade
     */
    public SuggestedTradeRecommendation getTrade()
    {
        return trade;
    }
}

Mise à jour: j'ai changé mon code pour qu'il ressemble à ceci:

package com.domain.idea;

import javax.persistence.CascadeType;
import javax.persistence.FetchType;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import org.hibernate.annotations.AccessType;

/**
 * object model for the view [InvestmentReturn].[vMAE_MFE]
 */
@Entity
@Table(name="vMAE_MFE", schema="InvestmentReturn")
@AccessType("field")
public class MAE_MFEView
{
    /**
     * trade property is a SuggestdTradeRecommendation object
     */
    @Id
    @OneToOne(fetch = FetchType.LAZY , cascade = { CascadeType.PERSIST })
    @JoinColumn(name = "suggestedTradeRecommendationID")
    private SuggestedTradeRecommendation trade;

    /**
     * Most Adeverse Excursion value
     */
    private int MAE;

    public int getMAE()
    {
        return MAE;
    }

    /**
     * Most Favorable Excursion value
     */
    private int MFE;

    public int getMFE()
    {
        return MFE;
    }

    /**
     * @return trade property
     * see #trade
     */
    public SuggestedTradeRecommendation getTrade()
    {
        return trade;
    }
}

mais maintenant je reçois cette exception:

Caused by: org.hibernate.MappingException: Could not determine type for: com.domain.idea.SuggestedTradeRecommendation, at table: vMAE_MFE, for columns: [org.hibernate.mapping.Column(trade)]
    at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:292)
    at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:276)
    at org.hibernate.mapping.RootClass.validate(RootClass.java:216)
    at org.hibernate.cfg.Configuration.validate(Configuration.java:1135)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1320)
    at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:867)
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:669)
    ... 145 more
Ramy
la source
btw, sans rapport avec la question, c'est un stacktrace assez long. Vous avez des invocations répétées. Êtes-vous sûr que tout est correct là-bas.
Bozho
Je ne sais pas trop pourquoi les traces de pile sont toujours aussi longues. Je pense que de nombreux services d'arrière-plan en cours d'exécution sont affectés.
Ramy
Faites attention si votre identifiant n'est pas statique ou certains attributs de votre classe. C'est arrivé avec moi :)
Gean Felipe

Réponses:

434

Il vous manque un champ annoté avec @Id. Chacun a @Entitybesoin d'un @Id- c'est la clé primaire de la base de données.

Si vous ne souhaitez pas que votre entité soit conservée dans une table distincte, mais plutôt faire partie d'autres entités, vous pouvez utiliser à la @Embeddableplace de @Entity.

Si vous voulez simplement qu'un objet de transfert de données contienne certaines données de l'entité d'hibernation, n'utilisez aucune annotation dessus - laissez-le un simple pojo.

Mise à jour: En ce qui concerne les vues SQL, les documents Hibernate écrivent:

Il n'y a aucune différence entre une vue et une table de base pour un mappage Hibernate. C'est transparent au niveau de la base de données

Bozho
la source
2
Je dois avoir un champ @Id? Ma vue n'a pas, à proprement parler, une pièce d'identité.
Ramy
Que voulez-vous dire "voir". Il n'y a pas de "vue" dans Hibernate. Il n'y a qu'un modèle.
Bozho
1
eh bien, attribuez un identifiant à la vue. Je ne peux pas m'en passer. Chaque ligne (objet) doit être identifiée de manière unique.
Bozho
obtenir une nouvelle exception après l'ajout de @Id
Ramy
3
Je vous remercie! Cela a corrigé une NullPointerFromHellException ennuyeuse!
malix
173

Pour moi, javax.persistence.Iddevrait être utilisé à la place de org.springframework.data.annotation.Id. Pour tous ceux qui ont rencontré ce problème, vous pouvez vérifier si vous avez importé la bonne Idclasse.

Searene
la source
2
Tu m'as sauvé la journée: ')
Amitrajit Bose
avait un problème similaire.
AngelThread
59

Cette erreur peut être levée lorsque vous importez une bibliothèque différente pour @Id que Javax.persistance.Id ; Vous devrez peut-être aussi faire attention à ce cas

Dans mon cas, j'avais

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Table;

import org.springframework.data.annotation.Id;

@Entity
public class Status {

    @Id
    @GeneratedValue
    private int id;

quand je change le code comme ça, ça marche

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Table;

import javax.persistence.Id;

@Entity
public class Status {

    @Id
    @GeneratedValue
    private int id;
Tadele Ayelegn
la source
1
précieux conseils .. obsolète org.springframework.data.annotation.Id plz
Christian Meyer
13

Le code ci-dessous peut résoudre l'exception NullPointerException.

@Id
@GeneratedValue
@Column(name = "STOCK_ID", unique = true, nullable = false)
public Integer getStockId() {
    return this.stockId;
}
public void setStockId(Integer stockId) {
    this.stockId = stockId;
}

Si vous ajoutez @Id, vous pouvez en déclarer plus comme la méthode déclarée ci-dessus.

Shivendra Prakash Shukla
la source
becoz ur @Id value n'a pas assigné et mis à jour n'importe où qui a une exception de pointeur nul ...
Shivendra Prakash Shukla
2

Je sais que ça semble fou, mais j'ai reçu une telle erreur parce que j'oublie de supprimer

private static final long serialVersionUID = 1L;

généré automatiquement par l'outil Eclipse JPA lors de la transformation d'une table en entités que j'ai effectuée.

Suppression de la ligne ci-dessus qui a résolu le problème

ittradco
la source
1

L'utilisation de @EmbeddableId pour l'entité PK a résolu mon problème.

@Entity
@Table(name="SAMPLE")
 public class SampleEntity implements Serializable{
   private static final long serialVersionUID = 1L;

   @EmbeddedId
   SampleEntityPK id;

 }
Venkatesh Ramoju
la source
1

Je pense que ce problème après une mauvaise importation de classe de modèle.

    import org.springframework.data.annotation.Id;

Normalement, ce devrait être:

    import javax.persistence.Id;
Mahendra Sri
la source
1

TL; DR

Il vous manque la @Idpropriété d'entité, et c'est pourquoi Hibernate lève cette exception.

Identifiants d'entité

Toute entité JPA doit avoir une propriété d'identifiant, marquée par l' Idannotation.

Il existe deux types d'identifiants:

  • attribué
  • genere automatiquement

Identifiants attribués

Un identifiant attribué se présente comme suit:

@Id
private Long id;

Notez que nous utilisons un emballage (par exemple Long, Integer) au lieu d'un type primitif (par exemple long, int). L'utilisation d'un type wrapper est un meilleur choix lorsque vous utilisez Hibernate car, en vérifiant si l' idest nullou non, Hibernate peut mieux déterminer si une entité est transitoire (elle n'a pas de ligne de table associée) ou détachée (elle a une ligne de table associée, mais il n'est pas géré par le contexte de persistance actuel).

L'identifiant attribué doit être défini manuellement par l'application avant d'appeler persist:

Post post = new Post();
post.setId(1L);

entityManager.persist(post);

Identifiants générés automatiquement

Un identifiant généré automatiquement nécessite l' @GeneratedValueannotation en plus de @Id:

@Id
@GeneratedValue
private int id;

Comme je l'ai expliqué dans cet article , Hibernate peut utiliser 3 stratégies pour générer automatiquement l'identifiant d'entité:

  • IDENTITY
  • SEQUENCE
  • TABLE

La IDENTITYstratégie est à éviter si la base de données sous-jacente prend en charge des séquences (par exemple, Oracle, PostgreSQL, MariaDB depuis 10.3 , SQL Server depuis 2012). La seule base de données majeure qui ne prend pas en charge les séquences est MySQL.

Le problème avec IDENTITY est que les insertions par lots Hibernate automatiques sont désactivées pour cette stratégie. Pour plus de détails sur ce sujet, consultez cet article .

La SEQUENCEstratégie est le meilleur choix, sauf si vous utilisez MySQL. Pour le SEQUENCE stratégie, vous souhaitez également utiliser l' pooledoptimiseur pour réduire le nombre d'aller-retour de base de données lors de la persistance de plusieurs entités dans le même contexte de persistance.

Le TABLEgénérateur est un choix terrible car il n'est pas à l'échelle . Pour la portabilité, il vaut mieux utiliser SEQUENCEpar défaut et passer à IDENTITYpour MySQL uniquement, comme expliqué dans cet article .

Vlad Mihalcea
la source
Le premier exemple ne devrait pas avoir @GeneratedValue, non?
Josef Cech
0

Cette erreur a été provoquée par l'importation de la mauvaise classe d'ID. Après avoir modifié org.springframework.data.annotation.Id en javax.persistence.Id, l'exécution de l'application

Philip Afemikhe
la source