You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中jakarta.persistence.Check约束失效及导入报错问题

问题解决:演员关联电影时无法删除的约束实现及依赖冲突修复

你遇到的核心问题有两个:一是依赖版本冲突导致jakarta.persistence.Check无法被编译器识别,二是错误地在中间关联表上添加约束(你的需求是限制Actor的删除操作,而非中间表)。以下是具体解决步骤:

一、修复Gradle依赖冲突

Spring Boot 3.0.x基于Jakarta EE 9规范,必须使用适配Jakarta的依赖。你的gradle配置同时混入了旧版Java EE的javax.persistence-api和仅支持Java EE的Hibernate 5.x,导致类路径混乱。修改后的build.gradle如下:

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.0.5'
    id 'io.spring.dependency-management' version '1.1.0'
    id 'io.freefair.lombok' version '8.0.1'
}

group = 'com.bill'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    // 依赖Spring Boot Starter自动管理版本,无需手动指定JPA、Hibernate等组件版本
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-validation'
    implementation 'mysql:mysql-connector-java:8.0.32'

    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

tasks.named('test') {
    useJUnitPlatform()
}

tasks.withType(JavaCompile) {
    options.annotationProcessorPath = configurations.compileClasspath
}

修改说明:

  • 移除手动添加的spring-data-jpa、javax.persistence-api、jakarta.persistence-api、hibernate-core、hibernate-entitymanager,这些组件已由spring-boot-starter-data-jpa自动引入,版本与Spring Boot 3.0.5完全兼容(默认使用Hibernate 6.1.x,适配Jakarta EE 9)。
  • 将spring-boot-starter-validation版本统一为3.0.5,避免与Spring Boot 3.x版本冲突。

二、正确实现“关联电影的演员不可删除”约束

你的需求是:当Actor被关联到Movie时,禁止删除该Actor。推荐两种可靠实现方式:

方法1:外键约束(数据库原生支持,推荐)

通过配置外键的删除规则为RESTRICT,让数据库直接阻止删除关联了电影的演员。

修改Movie类的@ManyToMany关联配置:

import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.time.LocalDate;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name = "movies",
        uniqueConstraints = @UniqueConstraint(columnNames = {"title", "releaseDate"}))
public class Movie extends Media {

    @Column(nullable = false)
    private String title;

    @Column(nullable = false)
    private LocalDate releaseDate;

    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(
            name = "movie_actor",
            joinColumns = @JoinColumn(
                name = "movie_id", 
                foreignKey = @ForeignKey(
                    ConstraintMode.CONSTRAINT, 
                    name = "fk_movie", 
                    foreignKeyDefinition = "FOREIGN KEY (movie_id) REFERENCES movies(id) ON DELETE CASCADE"
                )
            ),
            inverseJoinColumns = @JoinColumn(
                name = "actor_id", 
                foreignKey = @ForeignKey(
                    ConstraintMode.CONSTRAINT, 
                    name = "fk_actor", 
                    foreignKeyDefinition = "FOREIGN KEY (actor_id) REFERENCES actors(id) ON DELETE RESTRICT"
                )
            ),
            uniqueConstraints = {@UniqueConstraint(columnNames = {"movie_id", "actor_id"})}
    )
    private Set<Actor> actors = new HashSet<>();

    // getter、setter等方法
}

也可以直接在Actor实体的关联字段上配置:

@Entity
@Table(name = "actors")
public class Actor {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    // 其他字段
    
    @ManyToMany(mappedBy = "actors", fetch = FetchType.LAZY)
    @OnDelete(action = OnDeleteAction.RESTRICT) // Hibernate自动生成ON DELETE RESTRICT的外键约束
    private Set<Movie> movies = new HashSet<>();
}

方法2:@Check约束(需数据库支持)

如果要使用@Check,需将约束添加到Actor的表上,同时开启Hibernate生成Check约束的配置:

  1. 在application.properties中添加配置:
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.check_constraints=true
  1. 修改Actor实体:
@Entity
@Table(name = "actors",
        constraints = @Check(constraints = "NOT EXISTS(SELECT * FROM movie_actor ma WHERE ma.actor_id = id)"))
public class Actor {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    // 其他字段及关联关系
}

注意:此方法依赖数据库对Check约束的支持(如PostgreSQL完全支持,MySQL 8.0.16+才会生效Check约束,旧版本仅语法兼容),因此更推荐方法1的外键约束方案。

内容的提问来源于stack exchange,提问作者WowBow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 22:32:44