hibernate异常:org.hibernate.AnnotationException:没有为实体指定标识符:com..domain.idea.MAE_MFEView

Ram*_*amy 186 orm hibernate jpa hibernate-annotations

为什么我得到这个例外?

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:我已将我的代码更改为如下所示:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

但现在我得到了这个例外:

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
Run Code Online (Sandbox Code Playgroud)

Boz*_*zho 399

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

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

如果你只想要一个数据传输对象来保存来自hibernate实体的一些数据,那么不要在它上面使用任何注释 - 留下一个简单的pojo.

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

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

  • 谢谢!这修复了烦人的NullPointerFromHellException! (3认同)
  • 我想代表一个表没有PK。不可能吗? (3认同)
  • 我必须有一个@Id字段吗?严格来讲,我的视图没有ID。 (2认同)
  • 换句话说,hibernate 不支持**没有**主键的表吗? (2认同)

Sea*_*ene 132

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

  • 你拯救了我的一天:') (6认同)

Tad*_*egn 53

导入@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;
Run Code Online (Sandbox Code Playgroud)

当我改变这样的代码时,它就变得有效了

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;
Run Code Online (Sandbox Code Playgroud)

  • 宝贵的建议..弃用 org.springframework.data.annotation.Id plz (5认同)

Shi*_*kla 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;
}
Run Code Online (Sandbox Code Playgroud)

如果你添加@Id,那么你可以声明一些更像上面声明的方法.


小智 6

我认为这个问题是由于模型类错误导入造成的。

    import org.springframework.data.annotation.Id;
Run Code Online (Sandbox Code Playgroud)

正常情况下,应该是:

    import javax.persistence.Id;
Run Code Online (Sandbox Code Playgroud)


Vla*_*cea 5

TL; 博士

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

实体标识符

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

有两种类型的标识符:

  • 分配
  • 自动生成

分配的标识符

分配的标识符如下所示:

@Id
private Long id;
Run Code Online (Sandbox Code Playgroud)

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

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

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

entityManager.persist(post);
Run Code Online (Sandbox Code Playgroud)

自动生成的标识符

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

@Id
@GeneratedValue
private int id;
Run Code Online (Sandbox Code Playgroud)

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

  • IDENTITY
  • SEQUENCE
  • TABLE

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

问题在于此策略禁用了IDENTITY自动Hibernate 批处理插入

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

TABLE发电机是一个可怕的选择,因为它不能扩展。为了可移植性,您最好SEQUENCE默认使用并切换到IDENTITY仅用于 MySQL。