Hibernate ném org.hibernate.AnnotationException: Không có định danh được chỉ định cho thực thể: com..domain.idea.MAE_MFEView


207

Tại sao tôi nhận được ngoại lệ này?

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

Cập nhật: Tôi đã thay đổi mã của mình để trông như thế này:

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

nhưng bây giờ tôi đang nhận được ngoại lệ này:

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, không liên quan đến câu hỏi, đó là một stacktrace khá dài. Bạn có một số lời kêu gọi lặp đi lặp lại. Bạn có chắc chắn mọi thứ đều đúng ở đó.
Bozho

không quá chắc chắn tại sao các dấu vết ngăn xếp luôn luôn rất dài. Tôi nghĩ rằng có rất nhiều dịch vụ nền đang chạy bị ảnh hưởng.
Ramy

Hãy chú ý nếu id của bạn không tĩnh hoặc một số thuộc tính trên lớp của bạn. Nó đã xảy ra với tôi :)
Gean Felipe

Câu trả lời:


433

Bạn đang thiếu một trường chú thích với @Id. Mỗi @Entitycần một @Id- đây là khóa chính trong cơ sở dữ liệu.

Nếu bạn không muốn thực thể của mình tồn tại trong một bảng riêng biệt, mà là một phần của các thực thể khác, bạn có thể sử dụng @Embeddablethay vì @Entity.

Nếu bạn chỉ muốn một đối tượng truyền dữ liệu để giữ một số dữ liệu từ thực thể ngủ đông, không sử dụng bất kỳ chú thích nào trên đó - hãy để nó một pojo đơn giản.

Cập nhật: Liên quan đến các chế độ xem SQL, tài liệu Hibernate viết:

Không có sự khác biệt giữa chế độ xem và bảng cơ sở cho ánh xạ Hibernate. Điều này là minh bạch ở cấp cơ sở dữ liệu


2
Tôi phải có trường @Id? Quan điểm của tôi không có, nói đúng ra là một ID.
Ramy

Bạn có ý nghĩa gì "xem". Không có "lượt xem" trong Hibernate. Chỉ có mô hình.
Bozho

1
tốt, chỉ định một số id cho xem. Không thể đi mà không có nó. Mỗi hàng (đối tượng) phải được xác định duy nhất.
Bozho

nhận được một ngoại lệ mới sau khi thêm @Id
Ramy

3
Cảm ơn bạn! Điều này đã sửa lỗi NullPulumFromHellException khó chịu!
malix

172

Đối với tôi, javax.persistence.Idnên được sử dụng thay vì org.springframework.data.annotation.Id. Đối với bất kỳ ai gặp phải vấn đề này, bạn có thể kiểm tra xem bạn đã nhập đúng Idlớp chưa.


2
Bạn đã cứu ngày của tôi: ')
Amitrajit Bose

đã có một vấn đề tương tự.
AngelThread

59

Lỗi này có thể được đưa ra khi bạn nhập một thư viện khác cho @Id so với Javax.persistance.Id ; Bạn có thể cần phải chú ý trường hợp này quá

Trong trường hợp của tôi, tôi đã có

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;

Khi tôi thay đổi mã như thế này, nó đã hoạt động

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
lời khuyên có giá trị .. Không dùng nữa org.springframework.data.annotation.Id plz
Christian Meyer

13

Mã dưới đây có thể giải quyết NullPulumException.

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

Nếu bạn thêm @Id, sau đó bạn có thể khai báo một số giống như phương thức khai báo ở trên.


Giá trị của bạn không được gán và cập nhật bất cứ nơi nào bạn có ngoại lệ con trỏ null ...
Shivendra Prakash Shukla

2

Tôi biết nghe có vẻ điên rồ nhưng tôi đã nhận được lỗi như vậy vì tôi quên xóa

private static final long serialVersionUID = 1L;

được tạo tự động bởi công cụ JPA Eclipse khi chuyển đổi bảng thành các thực thể.

Xóa dòng trên đã giải quyết vấn đề


1

Sử dụng @EmbeddableId cho thực thể PK đã giải quyết vấn đề của tôi.

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

   @EmbeddedId
   SampleEntityPK id;

 }

1

Tôi nghĩ vấn đề này theo mô hình nhập sai.

    import org.springframework.data.annotation.Id;

Thông thường, nó nên là:

    import javax.persistence.Id;

1

TL; DR

Bạn đang thiếu thuộc tính @Idthực thể và đó là lý do tại sao Hibernate đang ném ngoại lệ đó.

Định danh thực thể

Bất kỳ thực thể JPA nào cũng phải có thuộc tính định danh, được đánh dấu bằng Idchú thích.

Có hai loại định danh:

  • giao
  • tự động tạo ra

Số nhận dạng được chỉ định

Một định danh được gán trông như sau:

@Id
private Long id;

Lưu ý rằng chúng tôi đang sử dụng một trình bao bọc (ví dụ Long,, Integer) thay vì một kiểu nguyên thủy (ví dụ long, int). Sử dụng loại trình bao bọc là lựa chọn tốt hơn khi sử dụng Hibernate bởi vì, bằng cách kiểm tra xem idnullhay không, Hibernate có thể xác định tốt hơn nếu một thực thể là tạm thời (nó không có một hàng bảng liên quan) hoặc tách ra (nó có một hàng bảng liên quan, nhưng nó không được quản lý bởi bối cảnh dai dẳng hiện tại).

Mã định danh được gán phải được cài đặt thủ công bởi ứng dụng trước khi gọi liên tục:

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

entityManager.persist(post);

Định danh tự động tạo

Mã định danh được tạo tự động yêu cầu @GeneratedValuechú thích bên cạnh @Id:

@Id
@GeneratedValue
private int id;

Như tôi đã giải thích trong bài viết này , có 3 chiến lược mà Hibernate có thể sử dụng để tự động tạo định danh thực thể:

  • IDENTITY
  • SEQUENCE
  • TABLE

Các IDENTITY chiến lược là để thể tránh được nếu cơ sở dữ liệu cơ bản hỗ trợ trình tự (ví dụ, Oracle, PostgreSQL, MariaDB từ 10,3 , SQL Server từ năm 2012). Cơ sở dữ liệu chính duy nhất không hỗ trợ các chuỗi là MySQL.

Vấn đề với IDENTITYlà việc chèn hàng loạt Hibernate tự động bị vô hiệu hóa cho chiến lược này. Để biết thêm chi tiết về chủ đề này, hãy xem bài viết này .

Các SEQUENCEchiến lược là sự lựa chọn tốt nhất, trừ khi bạn đang sử dụng MySQL. Đối với SEQUENCEchiến lược, bạn cũng muốn sử dụngpooled tối ưu hóa để giảm số lượng vòng tròn cơ sở dữ liệu khi duy trì nhiều thực thể trong cùng một bối cảnh liên tục.

Các TABLEmáy phát điện là một sự lựa chọn khủng khiếp vì nó không quy mô . Đối với tính di động, bạn nên sử dụng SEQUENCEtheo mặc định và chuyển sang IDENTITYchỉ sử dụng MySQL, như được giải thích trong bài viết này .


Ví dụ đầu tiên không nên có @GeneratedValue, phải không?
Josef Cech

0

Lỗi này là do nhập sai lớp Id. Sau khi thay đổi org.springframework.data.annotation.Id thành javax.persistence.Id ứng dụng chạy

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.