调用 init 方法失败;嵌套异常是 org.hibernate.AnnotationException:没有为实体指定标识符

Posted

技术标签:

【中文标题】调用 init 方法失败;嵌套异常是 org.hibernate.AnnotationException:没有为实体指定标识符【英文标题】:Invocation of init method failed; nested exception is org.hibernate.AnnotationException: No identifier specified for entity 【发布时间】:2020-01-03 22:10:51 【问题描述】:

我刚刚开始学习 Spring。当我尝试在 Spring in Action 书中编写 taco-cloud 应用程序时,我收到“没有为实体指定标识符”错误。在第 3 章中,我正在尝试使用 H2 数据库学习 JPA。

我的订单模型:

package com.example.tacocloud.models;

import lombok.Data;

import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Data
@Entity
@Table(name = "Taco_Order")
public class Order implements Serializable 

    ...

    @Id
    @GeneratedValue(strategy= GenerationType.AUTO)
    private Long id;
    private Date placedAt;

    @ManyToMany(targetEntity=Taco.class)
    private List<Taco> tacos = new ArrayList<>();

    public void addDesign(Taco design) 
        this.tacos.add(design);
    

    @PrePersist
    void placedAt() 
        this.placedAt = new Date();
    



我的 Ingredient.class 如下所示:

package com.example.tacocloud.models;

import lombok.AccessLevel;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;

import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

@Data
@RequiredArgsConstructor
@NoArgsConstructor(access= AccessLevel.PRIVATE, force=true)
@Entity // if I change it to Embedded I get unmapped ManyToMany error in my Ingredient class.

public class Ingredient 
    private final String id;
    private final String name;
    private final Type type;

    public static enum Type
        WRAP, PROTEIN, VEGGIES, CHEESE, SAUCE
    


还有我的炸玉米饼课:

package com.example.tacocloud.models;

import lombok.Data;

import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.Date;
import java.util.List;

@Data
@Entity
public class Taco 
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private Date createdAt;

    @NotNull
    @Size(min=5, message="Name must be at least 5 characters long")
    private  String name;
    @ManyToMany(targetEntity=Ingredient.class)
    @Size(min=1, message="You must choose at least 1 ingredient")
    private List<String> ingredients;

    @PrePersist
    void createdAt() 
        this.createdAt = new Date();
    


还有我的 sql 文件:

delete from Taco_Order_Tacos;
delete from Taco_Ingredients;
delete from Taco;
delete from Taco_Order;
delete from Ingredient;
insert into Ingredient (id, name, type)
                values ('FLTO', 'Flour Tortilla', 'WRAP');
insert into Ingredient (id, name, type)
                values ('COTO', 'Corn Tortilla', 'WRAP');
insert into Ingredient (id, name, type)
                values ('GRBF', 'Ground Beef', 'PROTEIN');
insert into Ingredient (id, name, type)
                values ('CARN', 'Carnitas', 'PROTEIN');
insert into Ingredient (id, name, type)
                values ('TMTO', 'Diced Tomatoes', 'VEGGIES');
insert into Ingredient (id, name, type)
                values ('LETC', 'Lettuce', 'VEGGIES');
insert into Ingredient (id, name, type)
                values ('CHED', 'Cheddar', 'CHEESE');
insert into Ingredient (id, name, type)
                values ('JACK', 'Monterrey Jack', 'CHEESE');
insert into Ingredient (id, name, type)
                values ('SLSA', 'Salsa', 'SAUCE');
insert into Ingredient (id, name, type)
                values ('SRCR', 'Sour Cream', 'SAUCE');

schema.sql:

create table if not exists Ingredient (
  id varchar(4) not null,
  name varchar(25) not null,
  type varchar(10) not null
);
create table if not exists Taco (
  id identity,
  name varchar(50) not null,
  createdAt timestamp not null
);
create table if not exists Taco_Ingredients (
  taco bigint not null,
  ingredient varchar(4) not null
);
alter table Taco_Ingredients
    add foreign key (taco) references Taco(id);
alter table Taco_Ingredients
    add foreign key (ingredient) references Ingredient(id);
create table if not exists Taco_Order (
  id identity,
    deliveryName varchar(50) not null,
    deliveryStreet varchar(50) not null,
    deliveryCity varchar(50) not null,
    deliveryState varchar(2) not null,
    deliveryZip varchar(10) not null,
    ccNumber varchar(16) not null,
    ccExpiration varchar(5) not null,
    ccCVV varchar(3) not null,
    placedAt timestamp not null
);
create table if not exists Taco_Order_Tacos (
  tacoOrder bigint not null,
  taco bigint not null
);
alter table Taco_Order_Tacos
    add foreign key (tacoOrder) references Taco_Order(id);
alter table Taco_Order_Tacos
    add foreign key (taco) references Taco(id);

顺便说一句,我的 application.properties:

spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driver-class-name = org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect

谢谢。

【问题讨论】:

【参考方案1】:

您的类Ingredient 没有@Id 字段,而且它是一个不可变对象类,不适合序列化类-您必须像其他所有类一样具有默认构造函数。去掉@NoArgsConstructor(access= AccessLevel.PRIVATE, force=true)很奇怪,会混淆你的框架

【讨论】:

以上是关于调用 init 方法失败;嵌套异常是 org.hibernate.AnnotationException:没有为实体指定标识符的主要内容,如果未能解决你的问题,请参考以下文章

HTTP状态500-请求处理失败;嵌套的异常是java.lang.NullPointerException?

@Query ,存储库中的错误

使用dubbo引用和发布服务时出现的异常:HTTP状态500 - 请求处理失败; 嵌套异常是com.alibaba.dubbo.rpc.RpcException:无法在服务cn.e3mall.serv

创建名为“jpaMappingContext”的 bean 时出错:调用 init 方法失败

无法提交 Hibernate 事务;嵌套异常是 org.hibernate.Transaction 异常:JDBC 提交失败

Bug解决:获取JDBC连接失败;嵌套异常是java.sql.SQLException:无法从底层数据库获取连接