【问题标题】:Hibernate throws org.hibernate.AnnotationException: No identifier specified for entity: com..domain.idea.MAE_MFEViewHibernate 抛出 org.hibernate.AnnotationException:没有为实体指定标识符:com..domain.idea.MAE_MFEView
【发布时间】:2011-05-21 20:16:27
【问题描述】:

为什么会出现这个异常?

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 是否不是静态的或您的班级的某些属性。它发生在我身上:)

标签: hibernate jpa orm identifier hibernate-annotations


【解决方案1】:

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

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

如果您只是想要一个数据传输对象来保存来自休眠实体的一些数据,请不要在其上使用任何注释 - 将其保留为简单的 pojo。

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

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

【讨论】:

  • 我必须有一个@Id 字段?严格来说,我的视图没有 ID。
  • 好吧,给视图分配一些 id。不能没有它。每一行(对象)都必须被唯一标识。
  • 谢谢!这修复了一个恼人的 NullPointerFromHellException!
  • 也就是说,hibernate不支持没有主键的表吗?
  • 我想表示一个没有PK的表。不可能吗?
【解决方案2】:

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

【讨论】:

  • 你拯救了我的一天:')
  • 遇到了类似的问题。
【解决方案3】:

当您为 @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;

【讨论】:

  • 宝贵建议.. 弃用 org.springframework.data.annotation.Id plz
【解决方案4】:

下面的代码可以解决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,那么你可以声明一些更像上面声明的方法。

【讨论】:

  • 因为你的 @Id 值没有分配和更新任何你有空指针异常的地方......
【解决方案5】:

我认为这个问题是模型类错误导入之后的问题。

    import org.springframework.data.annotation.Id;

通常应该是:

    import javax.persistence.Id;

【讨论】:

    【解决方案6】:

    TL;DR

    您缺少 @Id 实体属性,这就是 Hibernate 抛出该异常的原因。

    实体标识符

    任何 JPA 实体都必须有一个标识符属性,该属性标有 Id 注释。

    有两种类型的标识符:

    • 已分配
    • 自动生成

    分配的标识符

    分配的标识符如下所示:

    @Id
    private Long id;
    

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

    分配的标识符必须在调用persist之前由应用手动设置:

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

    自动生成的标识符

    除了@Id,自动生成的标识符还需要@GeneratedValue注解:

    @Id
    @GeneratedValue
    private int id;
    

    Hibernate 可以使用 3 种策略来自动生成实体标识符:

    • IDENTITY
    • SEQUENCE
    • TABLE

    如果底层数据库支持序列(例如,Oracle、PostgreSQL、MariaDB since 10.3、自 2012 年以来的 SQL Server),则应避免使用 IDENTITY 策略。唯一不支持序列的主要数据库是 MySQL。

    IDENTITY 的问题在于自动 Hibernate batch inserts are disabled for this strategy

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

    TABLE 生成器是一个糟糕的选择,因为it does not scale。为便于移植,you are better off using SEQUENCE by default and switch to IDENTITY 仅适用于 MySQL。

    【讨论】:

    • 第一个例子应该没​​有@GeneratedValue吧?
    【解决方案7】:

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

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

    【讨论】:

    • 您的回复引用了两个注释,其中一个似乎不存在 (@EmbeddableId)
    【解决方案8】:
    1. 这个错误是由于导入了错误的包:
      import javax.persistence.Id;
    2. 并且您应该始终为表提供主键,否则会报错。

    【讨论】:

      【解决方案9】:

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

      private static final long serialVersionUID = 1L;
      

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

      删除上面解决问题的行

      【讨论】:

        【解决方案10】:

        此错误是由导入错误的 Id 类引起的。将 org.springframework.data.annotation.Id 更改为 javax.persistence.Id 后,应用程序运行

        【讨论】:

          猜你喜欢
          • 2014-04-06
          • 2015-07-25
          • 2016-01-31
          • 2020-05-02
          • 2013-02-25
          • 2021-05-19
          • 2014-11-09
          • 1970-01-01
          相关资源
          最近更新 更多