Hibernate löst org.hibernate.AnnotationException aus: Für die Entität wurde kein Bezeichner angegeben: com..domain.idea.MAE_MFEView

207

Warum bekomme ich diese Ausnahme?

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;
    }
}

Update: Ich habe meinen Code so geändert, dass er so aussieht:

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;
    }
}

aber jetzt bekomme ich diese Ausnahme:

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
quelle
Übrigens, unabhängig von der Frage, ist das eine ziemlich lange Stapelspur. Sie haben einige wiederholte Aufrufe. Sind Sie sicher, dass dort alles korrekt ist?
Bozho
Ich bin mir nicht sicher, warum die Stapelspuren immer so lang sind. Ich denke, es werden viele Hintergrunddienste ausgeführt, die betroffen sind.
Ramy
Achten Sie darauf, ob Ihre ID nicht statisch ist oder einige Attribute in Ihrer Klasse. Es ist mit mir passiert :)
Gean Felipe

Antworten:

433

Ihnen fehlt ein mit Anmerkungen versehenes Feld @Id. Jeder @Entitybenötigt einen @Id- dies ist der Primärschlüssel in der Datenbank.

Wenn Sie nicht möchten, dass Ihre Entität in einer separaten Tabelle gespeichert wird, sondern Teil anderer Entitäten ist, können Sie @Embeddablestattdessen verwenden @Entity.

Wenn Sie einfach möchten, dass ein Datenübertragungsobjekt einige Daten aus der Entität im Ruhezustand enthält, verwenden Sie keinerlei Anmerkungen dazu - lassen Sie es ein einfaches Pojo.

Update: In Bezug auf SQL-Ansichten schreiben Hibernate-Dokumente:

Es gibt keinen Unterschied zwischen einer Ansicht und einer Basistabelle für eine Zuordnung im Ruhezustand. Dies ist auf Datenbankebene transparent

Bozho
quelle
2
Ich muss ein @ ID-Feld haben? Meiner Ansicht nach hat es streng genommen keinen Ausweis.
Ramy
Was meinst du mit "Ansicht". Im Ruhezustand gibt es keine "Ansicht". Es gibt nur Modell.
Bozho
1
Nun, weisen Sie der Ansicht eine ID zu. Ich kann nicht ohne gehen. Jede Zeile (Objekt) muss eindeutig identifiziert werden.
Bozho
Erhalten einer neuen Ausnahme nach dem Hinzufügen von @Id
Ramy
3
Danke dir! Dies hat eine nervige NullPointerFromHellException behoben!
Malix
171

Für mich javax.persistence.Idsollte statt verwendet werden org.springframework.data.annotation.Id. Für alle, die auf dieses Problem gestoßen sind, können Sie überprüfen, ob Sie die richtige IdKlasse importiert haben .

Searene
quelle
1
Du hast meinen Tag gerettet: ')
Amitrajit Bose
hatte ein ähnliches Problem.
AngelThread
59

Dieser Fehler kann ausgelöst werden, wenn Sie eine andere Bibliothek für @Id als Javax.persistance.Id importieren . Möglicherweise müssen Sie auch in diesem Fall aufpassen

In meinem Fall hatte ich

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;

Wenn ich den Code so ändere, hat es funktioniert

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
quelle
1
wertvolle Ratschläge .. veraltet org.springframework.data.annotation.Id plz
Christian Meyer
13

Der folgende Code kann die NullPointerException lösen.

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

Wenn Sie hinzufügen @Id, können Sie eine ähnliche Methode wie oben deklarieren.

Shivendra Prakash Shukla
quelle
weil Ihr @ ID-Wert nirgendwo zugewiesen und aktualisiert wurde, wo Sie eine Nullzeiger-Ausnahme haben ...
Shivendra Prakash Shukla
2

Ich weiß, klingt verrückt, aber ich habe einen solchen Fehler erhalten, weil ich vergessen habe, ihn zu entfernen

private static final long serialVersionUID = 1L;

Wird vom Eclipse JPA-Tool automatisch generiert, wenn ich eine Transformation von Tabelle zu Entitäten durchgeführt habe.

Durch Entfernen der obigen Zeile wurde das Problem behoben

ittradco
quelle
1

Die Verwendung von @EmbeddableId für die PK-Entität hat mein Problem gelöst.

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

   @EmbeddedId
   SampleEntityPK id;

 }
Venkatesh Ramoju
quelle
1

Ich denke, dieses Problem nach Modellklasse falscher Import.

    import org.springframework.data.annotation.Id;

Normalerweise sollte es sein:

    import javax.persistence.Id;
Mahendra Sri
quelle
1

TL; DR

Ihnen fehlt die @IdEntitätseigenschaft, und aus diesem Grund löst Hibernate diese Ausnahme aus.

Entitätskennungen

Jede JPA-Entität muss über eine Bezeichner-Eigenschaft verfügen, die mit der IdAnmerkung gekennzeichnet ist.

Es gibt zwei Arten von Bezeichnern:

  • zugewiesen
  • automatisch generiert

Zugewiesene Bezeichner

Eine zugewiesene Kennung sieht wie folgt aus:

@Id
private Long id;

Beachten Sie, dass wir einen Wrapper verwenden (zB Long, Integer) anstelle eines primitiven Typ (zB long, int). Die Verwendung eines Wrapper-Typs ist eine bessere Wahl, wenn Sie den Ruhezustand verwenden, da der Ruhezustand durch Überprüfen, ob dies der Fall idist nulloder nicht, besser feststellen kann, ob eine Entität vorübergehend ist (ihr ist keine Tabellenzeile zugeordnet) oder getrennt ist (ihr ist eine Tabellenzeile zugeordnet). Es wird jedoch nicht vom aktuellen Persistenzkontext verwaltet.

Die zugewiesene Kennung muss von der Anwendung manuell festgelegt werden, bevor der Aufruf persist:

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

entityManager.persist(post);

Automatisch generierte Bezeichner

Eine automatisch generierte Kennung erfordert die @GeneratedValueAnmerkung neben @Id:

@Id
@GeneratedValue
private int id;

Wie ich in diesem Artikel erklärt habe , gibt es drei Strategien, mit denen Hibernate die Entitätskennung automatisch generieren kann:

  • IDENTITY
  • SEQUENCE
  • TABLE

Die IDENTITYStrategie ist zu vermeiden, wenn die zugrunde liegende Datenbank Sequenzen unterstützt (z. B. Oracle, PostgreSQL, MariaDB seit 10.3 , SQL Server seit 2012). Die einzige wichtige Datenbank, die keine Sequenzen unterstützt, ist MySQL.

Das Problem dabei IDENTITYist, dass automatische Batch-Einfügungen im Ruhezustand für diese Strategie deaktiviert sind. Weitere Informationen zu diesem Thema finden Sie in diesem Artikel .

Die SEQUENCEStrategie ist die beste Wahl, es sei denn, Sie verwenden MySQL. Für die SEQUENCEStrategie möchten Sie auch den pooledOptimierer verwenden , um die Anzahl der Datenbank-Roundtrips zu verringern, wenn mehrere Entitäten im selben Persistenzkontext beibehalten werden.

Der TABLEGenerator ist eine schreckliche Wahl, weil er nicht skaliert . Aus Gründen der Portabilität sollten Sie SEQUENCEstandardmäßig besser verwenden und IDENTITYnur für MySQL wechseln , wie in diesem Artikel erläutert .

Vlad Mihalcea
quelle
Das erste Beispiel sollte nicht haben @GeneratedValue, oder?
Josef Cech
0

Dieser Fehler wurde durch den Import der falschen ID-Klasse verursacht. Nach dem Ändern von org.springframework.data.annotation.Id in javax.persistence.Id wird die Anwendung ausgeführt

Philip Afemikhe
quelle