ไฮเบอร์เนตพ่น org.hibernate.AnnotationException: ไม่ได้ระบุตัวระบุสำหรับเอนทิตี: com..domain.idea.MAE_MFEView


207

เหตุใดฉันจึงได้รับข้อยกเว้นนี้

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

อัปเดต: ฉันเปลี่ยนรหัสของฉันเป็นแบบนี้:

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

แต่ตอนนี้ฉันได้รับข้อยกเว้นนี้:

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

btw ไม่เกี่ยวข้องกับคำถามนั่นคือ stacktrace ที่ค่อนข้างยาว คุณมีการเรียกใช้ซ้ำ คุณแน่ใจหรือว่าทุกอย่างถูกต้อง
Bozho

ไม่แน่ใจเกินไปว่าทำไมร่องรอยสแต็กนั้นยาวเสมอ ฉันคิดว่ามีบริการพื้นหลังจำนวนมากที่ได้รับผลกระทบ
Ramy

ให้ความสนใจถ้า ID ของคุณไม่คงที่หรือบางคุณสมบัติในชั้นเรียนของคุณ มันเกิดขึ้นกับฉัน :)
Gean Felipe

คำตอบ:


433

@Idคุณจะหายไปสนามกำกับด้วย แต่ละ@Entityความต้องการ@Id- นี่คือคีย์หลักในฐานข้อมูล

หากคุณไม่ต้องการที่นิติบุคคลของคุณจะยังคงอยู่ในตารางที่แยกจากกัน แต่เป็นส่วนหนึ่งของหน่วยงานอื่น ๆ ที่คุณสามารถใช้แทน@Embeddable@Entity

หากคุณต้องการเพียงแค่วัตถุการถ่ายโอนข้อมูลเพื่อเก็บข้อมูลบางอย่างจากเอนทิตีไฮเบอร์เนตให้ใช้คำอธิบายประกอบใด ๆ กับมัน - ปล่อยให้มันเป็น pojo ง่าย

อัปเดต: เกี่ยวกับมุมมอง SQL, Hibernate docs write:

ไม่มีความแตกต่างระหว่างมุมมองและตารางพื้นฐานสำหรับการทำแผนที่ไฮเบอร์เนต นี่คือความโปร่งใสในระดับฐานข้อมูล


2
ฉันต้องมีฟิลด์ @Id หรือไม่ มุมมองของฉันไม่มี ID พูดอย่างเคร่งครัด
Ramy

คุณหมายถึงอะไร "ดู" ไม่มี "มุมมอง" ใน Hibernate มีแบบจำลองเท่านั้น
Bozho

1
ดีกำหนด ID บางส่วนให้กับมุมมอง ไม่สามารถไปได้โดยปราศจากมัน แต่ละแถว (วัตถุ) จะต้องมีการระบุที่ไม่ซ้ำกัน
Bozho

รับข้อยกเว้นใหม่หลังจากเพิ่ม @Id
Ramy

3
ขอบคุณ! การแก้ไขนี้น่ารำคาญ NullPointerFromHellException!
malix

172

สำหรับผมควรจะนำมาใช้แทนjavax.persistence.Id org.springframework.data.annotation.Idสำหรับผู้ที่พบปัญหานี้คุณสามารถตรวจสอบว่าคุณนำเข้าIdชั้นเรียนที่ถูกต้องหรือไม่


2
คุณบันทึกวันของฉัน: ')
Amitrajit Bose

มีปัญหาที่คล้ายกัน
AngelThread

59

ข้อผิดพลาดนี้สามารถโยนได้เมื่อคุณนำเข้าห้องสมุดที่แตกต่างกันสำหรับ @Id กว่าJavax.persistance.Id ; คุณอาจต้องใส่ใจกับกรณีนี้ด้วย

ในกรณีของฉันฉันมี

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;

เมื่อฉันเปลี่ยนรหัสเช่นนี้มันก็ใช้ได้

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;

1
คำแนะนำที่มีค่า .. deprecate org.springframework.data.annotation.Id plz
Christian Meyer

13

รหัสด้านล่างสามารถแก้ไข 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;
}

หากคุณเพิ่ม@Idคุณสามารถประกาศวิธีอื่นตามที่ได้ประกาศไว้ข้างต้น


becoz ur @Id value ไม่ได้กำหนดและอัปเดตทุกที่ที่คุณมีข้อยกเว้นตัวชี้โมฆะ ...
Shivendra Prakash Shukla

2

ฉันรู้ว่ามันฟังดูบ้า แต่ฉันได้รับข้อผิดพลาดดังกล่าวเพราะฉันลืมที่จะลบ

private static final long serialVersionUID = 1L;

สร้างโดยอัตโนมัติโดยใช้เครื่องมือ Eclipse JPA เมื่อตารางไปยังการแปลงเอนทิตีที่ฉันทำ

การลบบรรทัดด้านบนเพื่อแก้ไขปัญหา


1

การใช้ @EmbeddableId สำหรับเอนทิตี PK ได้แก้ไขปัญหาของฉันแล้ว

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

   @EmbeddedId
   SampleEntityPK id;

 }

1

ฉันคิดว่าปัญหานี้หลังจากการนำเข้าคลาสผิดรุ่น

    import org.springframework.data.annotation.Id;

โดยปกติควรเป็น:

    import javax.persistence.Id;

1

TL; DR

คุณไม่มี@Idคุณสมบัติเอนทิตีและนี่คือสาเหตุที่ไฮเบอร์เนตกำลังส่งข้อยกเว้นดังกล่าว

ตัวระบุเอนทิตี

หน่วยงาน JPA ใด ๆ จะต้องมีคุณสมบัติตัวระบุที่มีการทำเครื่องหมายIdกำกับกำกับ

ตัวระบุมีสองประเภท:

  • ที่ได้รับมอบหมาย
  • สร้างขึ้นโดยอัตโนมัติ

ตัวระบุที่ได้รับมอบหมาย

ตัวระบุที่กำหนดมีลักษณะดังนี้:

@Id
private Long id;

โปรดสังเกตว่าเรากำลังใช้ wrapper (เช่นLong,, Integer) แทนประเภทดั้งเดิม (เช่นlong,, int) การใช้ประเภท wrapper เป็นตัวเลือกที่ดีกว่าเมื่อใช้ Hibernate เพราะโดยการตรวจสอบว่าidเป็นnullหรือไม่ไฮเบอร์เนตสามารถกำหนดได้ดีกว่าว่าเอนทิตีนั้นเป็นแบบชั่วคราว (ไม่มีแถวของตารางที่เกี่ยวข้อง) หรือแยกออก (มีแถวตารางที่เกี่ยวข้อง แต่ไม่ได้รับการจัดการโดยบริบทการคงอยู่ปัจจุบัน)

แอปพลิเคชั่นที่ได้รับมอบหมายจะต้องตั้งค่าด้วยตนเองก่อนที่จะโทรยังคงอยู่:

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

entityManager.persist(post);

ตัวระบุที่สร้างขึ้นอัตโนมัติ

ตัวระบุที่สร้างขึ้นโดยอัตโนมัติต้องการการเพิ่มความคิดเห็น@GeneratedValueนอกเหนือจาก@Id:

@Id
@GeneratedValue
private int id;

ดังที่ฉันได้อธิบายไว้ในบทความนี้มี 3 กลยุทธ์ที่ไฮเบอร์เนตสามารถใช้ในการสร้างตัวระบุเอนทิตีได้โดยอัตโนมัติ:

  • IDENTITY
  • SEQUENCE
  • TABLE

IDENTITYกลยุทธ์คือการหลีกเลี่ยงได้หากฐานข้อมูลต้นแบบสนับสนุนลำดับ (เช่น Oracle, PostgreSQL, MariaDB ตั้งแต่ 10.3 , SQL Server ตั้งแต่ 2012) ฐานข้อมูลหลักเท่านั้นที่ไม่สนับสนุนลำดับคือ MySQL

ปัญหาIDENTITYคือการที่เม็ดมีดไฮเบอร์เนตอัตโนมัติถูกปิดใช้งานสำหรับกลยุทธ์นี้ สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับหัวข้อนี้ตรวจสอบบทความนี้

SEQUENCEกลยุทธ์เป็นตัวเลือกที่ดีที่สุดสำหรับคุณจนกว่าคุณจะได้ใช้ MySQL สำหรับ SEQUENCEกลยุทธ์นี้คุณต้องการใช้pooledเครื่องมือเพิ่มประสิทธิภาพเพื่อลดจำนวนรอบของฐานข้อมูลเมื่อยังคงมีเอนทิตีหลายรายการในบริบทการคงอยู่เดิม

TABLEกำเนิดเป็นทางเลือกที่น่ากลัวเพราะมันไม่ได้ขนาด สำหรับการพกพาคุณจะดีกว่าการใช้SEQUENCEโดยค่าเริ่มต้นและสลับไปIDENTITYสำหรับ MySQL เท่านั้นที่อธิบายไว้ในบทความนี้


ตัวอย่างแรกไม่ควร@GeneratedValueใช่ไหม
Josef Cech

0

ข้อผิดพลาดนี้เกิดจากการนำเข้าคลาส Id ที่ไม่ถูกต้อง หลังจากเปลี่ยน org.springframework.data.annotation.Id เป็น javax.persistence.Id ให้รันแอปพลิเคชัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.