Hibernate引发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

顺便说一句,与问题无关,这是一个相当长的堆栈跟踪。您有一些重复的调用。您确定那里一切正确吗?
博佐

不太清楚为什么堆栈跟踪总是这么长。我认为有许多正在运行的后台服务受到影响。
拉米

如果您的ID不是静态的或类中的某些属性,请注意。这件事发生在我身上:)
Gean Felipe '18

Answers:


433

您缺少带注释的字段@Id。每个都@Entity需要一个@Id-这是数据库中的主键。

如果您不希望您的实体保存在单独的表中,而是希望成为其他实体的一部分,则可以使用@Embeddable代替@Entity

如果您只想让数据传输对象保存来自休眠实体的某些数据,则不对它进行任何注释-将其保留为简单的pojo。

更新:关于SQL视图,Hibernate文档写道:

Hibernate映射的视图和基表之间没有区别。这在数据库级别是透明的


2
我必须有一个@Id字段吗?严格来讲,我的视图没有ID。
拉米

你是什​​么意思“观点”。Hibernate中没有“视图”。只有模特。
博若

1
好吧,给视图分配一些ID。不能没有它。每行(对象)必须唯一标识。
博佐

添加@Id后收到新的异常
Ramy 2010年

3
谢谢!这修复了一个烦人的NullPointerFromHellException!
malix

172

对我而言,javax.persistence.Id应使用代替org.springframework.data.annotation.Id。对于遇到此问题的任何人,您都可以检查是否导入了正确的Id类。


2
您保存了我的一天:')
阿米特拉吉特·玻色

有类似的问题。
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
有价值的建议..弃用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值未分配和更新任何存在空指针异常的地方……
Shivendra Prakash Shukla 2015年

2

我知道听起来很疯狂,但因为忘记删除而收到了这样的错误

private static final long serialVersionUID = 1L;

表到实体的转换完成后,由Eclipse JPA工具自动生成。

删除上面解决问题的行


1

对PK实体使用@EmbeddableId解决了我的问题。

@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实体属性,这就是Hibernate抛出该异常的原因。

实体标识符

任何JPA实体都必须具有一个带有Id注释标记的标识符属性。

标识符有两种类型:

  • 已分配
  • 自动产生

分配的标识符

分配的标识符如下所示:

@Id
private Long id;

请注意,我们使用的是包装器(例如,LongInteger),而不是原始的类型(例如,longint)。使用Hibernate时,使用包装器类型是一个更好的选择,因为通过检查是否idnullHibernate,Hibernate可以更好地确定一个实体是瞬态的(它没有关联的表行)还是分离的(它有一个关联的表行,但不受当前的持久性上下文管理)。

必须在调用持久化之前由应用程序手动设置分配的标识符:

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

entityManager.persist(post);

自动生成的标识符

自动生成的标识符@GeneratedValue除了需要以下注释@Id

@Id
@GeneratedValue
private int id;

正如我在本文中所解释的,Hibernate可以使用三种策略来自动生成实体标识符:

  • IDENTITY
  • SEQUENCE
  • TABLE

IDENTITY如果基础数据库支持序列(例如,自10.3起的 Oracle,PostgreSQL,MariaDB,自2012年起的 SQL Server),则应避免使用该策略。MySQL不支持序列的唯一主要数据库。

问题IDENTITY在于此策略禁用了自动休眠批处理插入。有关此主题的更多详细信息,请参阅本文

SEQUENCE除非使用MySQL,否则该策略是最佳选择。对于该 SEQUENCE策略,当将多个实体持久存储在同一持久性上下文中时,您还希望使用pooled优化器来减少数据库往返的次数。

TABLE发电机是一个可怕的选择,因为它不能扩展。为了实现可移植性,最好SEQUENCE不要使用默认设置,IDENTITY而只切换到MySQL,如本文所述


第一个例子不应该有@GeneratedValue吧?
约瑟夫·切赫

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.