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

时间:2010-12-07 20:33:08

标签: hibernate jpa orm 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;
    }
}

更新:我已将代码更改为:

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

10 个答案:

答案 0 :(得分:359)

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

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

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

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

  

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

答案 1 :(得分:110)

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

答案 2 :(得分:45)

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

答案 3 :(得分: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,那么你可以声明一些更像上面声明的方法。

答案 4 :(得分:3)

我认为模型类导入后出现此问题。

    import org.springframework.data.annotation.Id;

通常应该是:

    import javax.persistence.Id;

答案 5 :(得分:3)

TL; DR

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

实体标识符

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

有两种类型的标识符:

  • 已分配
  • 自动生成

分配的标识符

分配的标识符如下:

@Id
private Long id;

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

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

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

entityManager.persist(post);

自动生成的标识符

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

@Id
@GeneratedValue
private int id;

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

  • IDENTITY
  • SEQUENCE
  • TABLE

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

IDENTITY的问题在于,此策略禁用了自动Hibernate批处理插入。有关此主题的更多详细信息,请查看this article

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

TABLE生成器是一个糟糕的选择,因为it does not scale。对于可移植性,最好在默认情况下使用SEQUENCE并仅针对MySQL切换到IDENTITY,如this article中所述。

答案 6 :(得分:2)

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

private static final long serialVersionUID = 1L;

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

删除上面已解决问题的行

答案 7 :(得分:2)

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

答案 8 :(得分:1)

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

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

   @EmbeddedId
   SampleEntityPK id;

 }

答案 9 :(得分:0)

  1. 由于导入错误的程序包而发生此错误:
    import javax.persistence.Id;
  2. 并且您应该始终将主键提供给表,否则将产生错误。