首页 > 解决方案 > Spring Boot Data JPA manyToMany 添加项抛出 UnsupportedOperationException

问题描述

公司.java:

@Entity
@JsonIdentityInfo(generator= ObjectIdGenerators.PropertyGenerator.class, property="id")
@Data
public class Company {
    @Id
    @GeneratedValue(generator="system-uuid")
    @GenericGenerator(name="system-uuid", strategy = "uuid")
    String id;

    String name;

    @ManyToMany
    @LazyCollection(LazyCollectionOption.FALSE)
    private List<User> employees = new ArrayList<>();
    // Snip
}

用户

@Entity
@JsonIdentityInfo(generator= ObjectIdGenerators.PropertyGenerator.class, property="id")
@Data
public class User {
    @Id @GeneratedValue(generator="system-uuid")
    @GenericGenerator(name="system-uuid", strategy = "uuid")
    String id;

    @NotNull
    String email;

    @NotNull
    Date created = new Date();

    @ManyToMany(mappedBy="employees")
    @LazyCollection(LazyCollectionOption.FALSE)
    List<Company> employedByCompanies = new ArrayList<>();
    // Snip
}

存储库:

public interface CompanyRepository extends CrudRepository<Company, String> {
}

public interface UserRepository extends CrudRepository<User, String> {
}

所以我从数据库加载一家公司并执行以下操作:

company.getEmployees().add(timesheetUser);

我得到了例外:

java.lang.UnsupportedOperationException
    at java.util.AbstractList.add(AbstractList.java:148)

为什么 JPA 不使用我可以更新的类?

这是我的gradle文件:

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:2.0.3.RELEASE")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

bootJar {
    baseName = 'timesheets-rest-service'
    version =  '0.1.0'
}

repositories {
    mavenCentral()
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies {
    compile("io.jsonwebtoken:jjwt-api:0.10.5")
    compile("io.jsonwebtoken:jjwt-impl:0.10.5")

    compile("org.springframework.boot:spring-boot-starter-web")
    compile("org.springframework.boot:spring-boot-starter-security")
    compile("org.springframework.cloud:spring-cloud-starter-config")
    compile("org.springframework.boot:spring-boot-starter-data-jpa")
    compile('org.springframework.boot:spring-boot-starter-actuator')

    compile group: 'org.springframework.security.oauth.boot', name: 'spring-security-oauth2-autoconfigure', version: '2.0.3.RELEASE'

    compile("com.h2database:h2")
    compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.7'
    compile group: 'com.google.guava', name: 'guava', version: '26.0-jre'
    compileOnly 'org.projectlombok:lombok:1.18.2'
    runtime 'io.jsonwebtoken:jjwt-impl:0.10.5',
            // Uncomment the next line if you want to use RSASSA-PSS (PS256, PS384, PS512) algorithms:
            //'org.bouncycastle:bcprov-jdk15on:1.60',
            'io.jsonwebtoken:jjwt-jackson:0.10.5'

    testCompile('org.springframework.boot:spring-boot-starter-test')
}

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:Finchley.BUILD-SNAPSHOT"
    }
}

repositories {
    maven {
        url 'https://repo.spring.io/libs-milestone'
    }
    maven {
        url 'https://repo.spring.io/libs-snapshot'
    }
}

标签: javaspringspring-bootspring-data-jpamany-to-many

解决方案


无论出于何种原因,我不得不更改ListSet并且它有效。

像这样:

@Entity
@JsonIdentityInfo(generator= ObjectIdGenerators.PropertyGenerator.class, property="id")
@Data
public class User {
    @Id @GeneratedValue(generator="system-uuid")
    @GenericGenerator(name="system-uuid", strategy = "uuid")
    String id;

    @NotNull
    String email;

    @NotNull
    Date created = new Date();

    @ManyToMany(mappedBy="employees")
    @LazyCollection(LazyCollectionOption.FALSE)
    // List DOES NOT WORK HERE!
    Set<Company> employedByCompanies = new HashSet<>();
    // Snip
}

不知道为什么...


推荐阅读