【问题标题】:java.lang.IllegalStateException: Required identifier property not foundjava.lang.IllegalStateException:找不到所需的标识符属性
【发布时间】:2019-10-10 17:28:29
【问题描述】:

我在尝试将对象保存到 H2 数据库时不断收到此异常。

我试图持久化的对象定义如下:

package mypackage.foo.core.jpa.domain;

@Entity
@Getter
@NoArgsConstructor
public class Task implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Setter
    private Long id;

    private String name;
    private String description;

控制器:

package mypackage.foo.core.web.controller;

@RestController
@RequiredArgsConstructor
public class TaskController {

    private final TaskService taskService;

    @PostMapping("/api/task/save")
    public ResponseEntity<Task> handlePostAddTask(@RequestBody Task task) {
        Task savedTask = taskService.save(task);

        return new ResponseEntity<>(savedTask, HttpStatus.CREATED);
    }
}

我通过 Postman 发送到该端点的有效负载:

{
    "name":"first task",
    "description":"some fascinating description"
}

存储库:

package mypackage.foo.core.jpa.repository;

@Repository
public interface TaskDao extends JpaRepository<Task, Long> {
}

应用配置:

@SpringBootApplication
@EnableJpaRepositories(basePackages = {"mypackage.foo.core.jpa.repository"})
@EntityScan(basePackages = {"mypackage.foo.core.jpa.domain"})
public class FooApplication {

    public static void main(String[] args) {
        SpringApplication.run(FooApplication.class, args);
    }

}

Maven 部门:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jdbc</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

我的方法: 第一个想法是,由于在Task 中缺少Id 的设置器,它一直在发生,但这并没有帮助。我一直想知道是否可以得到任何提示如何解决这个问题? 任何调用save(task) 的尝试都会导致IllegalStateException 被抛出。

TaskService 中的save(Task task) 本质上是调用taskDao.save(Task task)

我也怀疑错误的@Id 注释(我的意思是来自错误的包),但这里不是这种情况。

【问题讨论】:

  • 您有 h2 控制台,您可以在其中检查您的表格的外观。您将获得更多调试信息 (baeldung.com/spring-boot-h2-database)。另外,您是否只是为了测试尝试过 GenerationType.AUTO 而不是 IDENTITY?
  • 只是为了验证,您使用的是javax.persistence.Id对吗?
  • @Kayaman 是的,没错
  • @Carlos 更改为 AUTO 导致不同的错误:org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: NULL not allowed for column "ID"; SQL 语句:INSERT INTO task (id, name, description, date_created, date_last_updated) VALUES (?, ?, ?, ?, ?) 基本相同的问题,但描述不同
  • 尝试进行基本测试,例如删除所有 lombok 内容并在该类上手动生成所有 getter 和 setter。可能与您的领域的知名度有关。

标签: java spring hibernate spring-boot illegalstateexception


【解决方案1】:
Use @Data annotation from lombok as given below. This will generate both setter & getter methods. I hope this will resolve the issue. 

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

import lombok.Data;

@Entity
@Data
public class Student {

    @Id
    @GeneratedValue
    private long id;
    private String firstName;
    private String lastName;


@Data Equivalent to @Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode.

~Satheesh

【讨论】:

  • 虽然这段代码 sn-p 可以解决问题,但including an explanation 确实有助于提高帖子的质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
  • @Satheesh Mekala 这将如何解决问题,因为我已经有了@Getter@Setter?此外,默认情况下,实体不应该对所有字段都有设置器,就构造函数而言——Hibernate 只需要 @NoArgsConstructor。
【解决方案2】:

事实证明,删除这两行有帮助:

@EnableJpaRepositories(basePackages = {"mypackage.foo.core.jpa.repository"})
@EntityScan(basePackages = {"mypackage.foo.core.jpa.domain"})

当我在切换到MySql后注意到同样的体验时,我开始认为问题一定出在我的配置上。我试图用ComponentScan 替换这些注释,但 IntelliJ 开始抱怨: Redundant declaration: @SpringBootApplication already applies given @ComponentScan

所以,我的想法是,也许这些 @EnableJpaRepositories@EntityScan 在这里根本不需要?删除它们有帮助。我不知道为什么。

【讨论】:

    猜你喜欢
    • 2021-12-06
    • 2019-10-10
    • 1970-01-01
    • 2020-06-15
    • 2021-06-27
    • 2014-04-22
    • 2016-05-25
    • 1970-01-01
    • 2015-05-03
    相关资源
    最近更新 更多