Hibernate 抛出 org.hibernate.AnnotationException:没有为实体指定标识符:com..domain.idea.MAE_MFEView

发布于 2024-10-06 16:01:33 字数 3215 浏览 6 评论 0原文

为什么我会收到此异常?

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

Why am I getting this exception?

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

Update: I've changed my code to look like this:

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

but now I'm getting this exception:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(15

看轻我的陪伴 2024-10-13 16:01:33

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

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

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

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

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

You are missing a field annotated with @Id. Each @Entity needs an @Id - this is the primary key in the database.

If you don't want your entity to be persisted in a separate table, but rather be a part of other entities, you can use @Embeddable instead of @Entity.

If you want simply a data transfer object to hold some data from the hibernate entity, use no annotations on it whatsoever - leave it a simple pojo.

Update: In regards to SQL views, Hibernate docs write:

There is no difference between a view and a base table for a Hibernate mapping. This is transparent at the database level

终止放荡 2024-10-13 16:01:33

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

如果您使用 IntelliJ(也许还有其他 IDE)的自动建议功能而没有仔细查看导入内容,通常会发生这种情况。

For me, javax.persistence.Id should be used instead of org.springframework.data.annotation.Id. For anyone who encountered this issue, you can check if you imported the right Id class.

This usually happens if you use IntelliJ's (and perhaps other IDEs too) auto-suggest feature without carefully looking at what the import will be.

℡寂寞咖啡 2024-10-13 16:01:33

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

This error can be thrown when you import a different library for @Id than Javax.persistance.Id ; You might need to pay attention this case too

In my case I had

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;

when I change the code like this, it got worked

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;
把昨日还给我 2024-10-13 16:01:33

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

The code below can solve the 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;
}

If you add @Id, then you can declare some more like as above declared method.

赠佳期 2024-10-13 16:01:33

TL;DR

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

实体标识符

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

有两种类型的标识符:

  • 分配的
  • 自动生成

分配的标识符

分配的标识符如下所示:

@Id
private Long id;

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

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

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

entityManager.persist(post);

自动生成的标识符

除了 @Id 之外,自动生成的标识符还需要 @GenerateValue 注解

@Id
@GeneratedValue
private int id;

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

  • IDENTITY
  • SEQUENCE
  • TABLE

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

IDENTITY 的问题是自动 此策略禁用 Hibernate 批量插入

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

TABLE 生成器是一个糟糕的选择,因为 它无法扩展。为了可移植性,您最好默认使用 SEQUENCE 并仅针对 MySQL 切换到 IDENTITY

TL;DR

You are missing the @Id entity property, and that's why Hibernate is throwing that exception.

Entity identifiers

Any JPA entity must have an identifier property, that is marked with the Id annotation.

There are two types of identifiers:

  • assigned
  • auto-generated

Assigned identifiers

An assigned identifier looks as follows:

@Id
private Long id;

Notice that we are using a wrapper (e.g., Long, Integer) instead of a primitive type (e.g., long, int).
Using a wrapper type is a better choice when using Hibernate because, by checking if the id is null or not, Hibernate can better determine if an entity is transient (it does not have an associated table row) or detached (it has an associated table row, but it's not managed by the current Persistence Context).

The assigned identifier must be set manually by the application prior to calling persist:

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

entityManager.persist(post);

Auto-generated identifiers

An auto-generated identifier requires the @GeneratedValue annotation besides the @Id:

@Id
@GeneratedValue
private int id;

There are 3 strategies Hibernate can use to auto-generate the entity identifier:

  • IDENTITY
  • SEQUENCE
  • TABLE

The IDENTITY strategy is to be avoided if the underlying database supports sequences (e.g., Oracle, PostgreSQL, MariaDB since 10.3, SQL Server since 2012). The only major database that does not support sequences is MySQL.

The problem with IDENTITY is that automatic Hibernate batch inserts are disabled for this strategy.

The SEQUENCE strategy is the best choice unless you are using MySQL. For the SEQUENCE strategy, you also want to use the pooled optimizer to reduce the number of database roundtrips when persisting multiple entities in the same Persistence Context.

The TABLE generator is a terrible choice because it does not scale. For portability, you are better off using SEQUENCE by default and switch to IDENTITY for MySQL only.

苏佲洛 2024-10-13 16:01:33

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

    import org.springframework.data.annotation.Id;

正常情况下,应该是:

    import javax.persistence.Id;

I think this issue following model class wrong import.

    import org.springframework.data.annotation.Id;

Normally, it should be:

    import javax.persistence.Id;
花期渐远 2024-10-13 16:01:33

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

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

   @EmbeddedId
   SampleEntityPK id;

 }

Using @EmbeddableId for the PK entity has solved my issue.

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

   @EmbeddedId
   SampleEntityPK id;

 }
善良天后 2024-10-13 16:01:33
  1. 出现此错误的原因是导入了错误的包:
    import javax.persistence.Id;
  2. 并且您应该始终为表提供主键,否则会给出一个错误。
  1. This error occurs due to importing the wrong package:
    import javax.persistence.Id;
  2. And you should always give the primary key to the table, otherwise it will give an error.
素衣风尘叹 2024-10-13 16:01:33

我忘记删除

private static final long serialVersionUID = 1L;

我知道听起来很疯狂,但我收到了这样的错误,因为当我完成表到实体的转换时,

由 Eclipse JPA 工具自动生成的错误。删除上面解决问题的行

I know sounds crazy but I received such error because I forget to remove

private static final long serialVersionUID = 1L;

automatically generated by Eclipse JPA tool when a table to entities transformation I've done.

Removing the line above that solved the issue

人疚 2024-10-13 16:01:33

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

This error was caused by importing the wrong Id class. After changing org.springframework.data.annotation.Id to javax.persistence.Id the application run

似梦非梦 2024-10-13 16:01:33

就我而言:
@Id注释是:“org.springframework.data.annotation.Id;”
将其替换为包:“javax.persistence.Id”后,应用程序运行良好。

In my case:
@Id annotation was: "org.springframework.data.annotation.Id;"
After replacing it with that of package: "javax.persistence.Id" the app worked fine.

鱼忆七猫命九 2024-10-13 16:01:33

我在使用 Intelij IDEA 创建 hibernate 会话时遇到了同样的问题。
错误是:

org.hibernate.AnnotationException:没有为实体指定标识符

如果在实体类中未使用 @ID 注释,则可能会导致此错误,但在我的情况下

解决方案对我有用:

我从我的 DAO 中删除了以下导入语句类

import jakarta.persistence.*;

并添加了

import javax.persistence.*;

许多用户建议的内容。

I had faced same issue while creating session with hibernate using Intelij IDEA.
Error was :

org.hibernate.AnnotationException: No identifier specified for entity

This error can caused if @ID annotation is not used in entity class but in my case

Solution Worked for me :

I removed the below import statement from my DAO class

import jakarta.persistence.*;

and added

import javax.persistence.*;

as many users suggested to do .

别闹i 2024-10-13 16:01:33

正如有人已经提到的,实体类缺少 @Id 注释,如果您要保留数据,则必须使用该注释。
同样,@Id 必须与 @Entity 具有相同的库。

含义:

javax.persistence.Entity 不能与 org.springframework.data.annotation.Id 一起使用。 Entity 和 Id 都必须是 Spring Data 或 Java Persistence API 的一部分。建议使用 Java Persistence API,因为它是通用的。

As somebody has already mentioned the Entity class is missing @Id annotation which is must in case you are persisting your data.
Again the @Id must be of same same library as of the @Entity.

Meaning:

javax.persistence.Entity will not work with org.springframework.data.annotation.Id. Both the Entity and Id must either part of Spring Data or Java Persistence API. It is advisable to use Java Persistence API as it is generic.

无法言说的痛 2024-10-13 16:01:33

我们需要照顾两个方面。
我。正确的导入
二.缺少注释

所需的注释是

import javax.persistence.Id;


需要的注释是

@Id

示例 Java 类

package com.oracle.dto;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.SequenceGenerator;

import lombok.AccessLevel;
import lombok.Data;
import lombok.Setter;

@Entity
@Data
public class Question {
    @Id
    @Setter(value = AccessLevel.NONE)
    @GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "queGen")
    @SequenceGenerator(name = "queGen",sequenceName = "questionS",initialValue = 1,allocationSize = 1)
    private Integer qId;
    @Column(name="question_text",length = 200)
    private String question;
    @OneToOne
    @JoinColumn(name = "answerId")
    private Answer answer;
}

There can be two areas where we need to look after.
i. correct imports
ii. missing annotations

annotation required is

import javax.persistence.Id;

and
annotation needed is

@Id

Sample Java Class

package com.oracle.dto;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.SequenceGenerator;

import lombok.AccessLevel;
import lombok.Data;
import lombok.Setter;

@Entity
@Data
public class Question {
    @Id
    @Setter(value = AccessLevel.NONE)
    @GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "queGen")
    @SequenceGenerator(name = "queGen",sequenceName = "questionS",initialValue = 1,allocationSize = 1)
    private Integer qId;
    @Column(name="question_text",length = 200)
    private String question;
    @OneToOne
    @JoinColumn(name = "answerId")
    private Answer answer;
}

陪你搞怪i 2024-10-13 16:01:33

如果您的表具有使每行唯一的字段组合,您可以使用复合键并且不需要 id 字段。

例如

@Entity
@Table(name = "food_nutrient")
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@ToString
@IdClass(CompositeKey.class)
@EqualsAndHashCode
public class FoodNutrient implements Serializable {

,如果 CompositeKey 是另一个类

public class CompositeKey implements Serializable {
    private Integer foodId;
    private Integer nutrientId;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        CompositeKey key = (CompositeKey) o;
        if (foodId != key.foodId) return false;
        return nutrientId == key.nutrientId;
    }

    @Override
    public int hashCode() {
        return Objects.hash(foodId, nutrientId);
    }
}

,那么您的表将有两个没有 id 字段的主键

+--------------+--------------+------+-----+---------+-------+
| Field        | Type         | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+-------+
| amount       | float        | YES  |     | NULL    |       |
| fdc_id       | int          | YES  |     | NULL    |       |
| food_id      | int          | NO   | PRI | NULL    |       |
| label_source | varchar(16)  | YES  |     | NULL    |       |
| name         | varchar(255) | YES  |     | NULL    |       |
| nutrient_id  | int          | NO   | PRI | NULL    |       |
| pct_dv       | int          | YES  |     | NULL    |       |
| unit_name    | varchar(16)  | YES  |     | NULL    |       |
+--------------+--------------+------+-----+---------+-------+

If your table has a combination of fields that make each row unique, you can use a composite key and don't need an id field.

For example

@Entity
@Table(name = "food_nutrient")
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@ToString
@IdClass(CompositeKey.class)
@EqualsAndHashCode
public class FoodNutrient implements Serializable {

Where CompositeKey is another class like

public class CompositeKey implements Serializable {
    private Integer foodId;
    private Integer nutrientId;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        CompositeKey key = (CompositeKey) o;
        if (foodId != key.foodId) return false;
        return nutrientId == key.nutrientId;
    }

    @Override
    public int hashCode() {
        return Objects.hash(foodId, nutrientId);
    }
}

Then your table will have two primary keys with no id field

+--------------+--------------+------+-----+---------+-------+
| Field        | Type         | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+-------+
| amount       | float        | YES  |     | NULL    |       |
| fdc_id       | int          | YES  |     | NULL    |       |
| food_id      | int          | NO   | PRI | NULL    |       |
| label_source | varchar(16)  | YES  |     | NULL    |       |
| name         | varchar(255) | YES  |     | NULL    |       |
| nutrient_id  | int          | NO   | PRI | NULL    |       |
| pct_dv       | int          | YES  |     | NULL    |       |
| unit_name    | varchar(16)  | YES  |     | NULL    |       |
+--------------+--------------+------+-----+---------+-------+
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文