spring - 使用 @OneToMany 或 @ManyToMany 定位未映射的类 : com. example.soasec.entities.User.roles[com.example.soasec.entities.Role]

标签 spring spring-boot intellij-idea spring-security

我正在尝试使用 Spring 构建带有身份验证的安全 REST API。

我通过以下方式创建了User类:

package com.example.soasec.entities;

import javax.persistence.*;
import java.util.List;


@Entity

public class User extends BaseEntity{

    private String username;
    private String password;
    @OneToMany(fetch = FetchType.EAGER, cascade=CascadeType.ALL)
    private List<Role> roles;
    private boolean active;


    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public List<Role> getRoles() {
        return roles;
    }

    public void setRoles(List<Role> roles) {
        this.roles = roles;
    }
}

IDE 在这行向我抛出错误 private List<Role> roles;当我单击它时,会出现以下消息: “一对多”属性值类型不应为“角色”

角色类别:

package com.example.soasec.entities;

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

public class Role {
    @Id
    @GeneratedValue
    private Long id;
    String name;

    Role(){}

    public Role(String name) {this.name=name;}

    public String getName(){return name; }

    public void setName(String name) {this.name= name; }
}

另外,我在尝试编译时遇到了这个问题

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-09-21 19:02:04.782 ERROR 7692 --- [  restartedMain] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: Use of @OneToMany or @ManyToMany targeting an unmapped class: com.example.soasec.entities.User.roles[com.example.soasec.entities.Role]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1786) ~[spring-beans-5.3.9.jar:5.3.9]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:602) ~[spring-beans-5.3.9.jar:5.3.9]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~[spring-beans-5.3.9.jar:5.3.9]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.9.jar:5.3.9]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.9.jar:5.3.9]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.9.jar:5.3.9]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.9.jar:5.3.9]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1154) ~[spring-context-5.3.9.jar:5.3.9]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:908) ~[spring-context-5.3.9.jar:5.3.9]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.9.jar:5.3.9]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) ~[spring-boot-2.5.4.jar:2.5.4]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) ~[spring-boot-2.5.4.jar:2.5.4]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:434) ~[spring-boot-2.5.4.jar:2.5.4]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:338) ~[spring-boot-2.5.4.jar:2.5.4]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343) ~[spring-boot-2.5.4.jar:2.5.4]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1332) ~[spring-boot-2.5.4.jar:2.5.4]
    at com.example.soasec.SoasecApplication.main(SoasecApplication.java:10) ~[classes/:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
    at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-2.5.4.jar:2.5.4]
Caused by: org.hibernate.AnnotationException: Use of @OneToMany or @ManyToMany targeting an unmapped class: com.example.soasec.entities.User.roles[com.example.soasec.entities.Role]
    at org.hibernate.cfg.annotations.CollectionBinder.bindManyToManySecondPass(CollectionBinder.java:1351) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
    at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:874) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
    at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:799) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
    at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:53) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1693) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1661) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:295) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1224) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1255) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58) ~[spring-orm-5.3.9.jar:5.3.9]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.3.9.jar:5.3.9]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409) ~[spring-orm-5.3.9.jar:5.3.9]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396) ~[spring-orm-5.3.9.jar:5.3.9]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.3.9.jar:5.3.9]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1845) ~[spring-beans-5.3.9.jar:5.3.9]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1782) ~[spring-beans-5.3.9.jar:5.3.9]
    ... 21 common frames omitted

如何解决该问题?

有用信息:

Java版本:11

JDK:openjdk-17

IntelliJ IDEA版本:2021.2.2

Spring启动版本:2.5.4

最佳答案

您有两种选择来解决此问题。

1) 将角色设为实体

@Entity
public class Role {
    @Id
    @GeneratedValue
    private Long id;
    String name;

    public Role(){}

    public Role(String name) {this.name=name;}

    public String getName(){return name; }

    public void setName(String name) {this.name= name; }
}

2) 使角色可嵌入

在这种情况下,元素完全归User所有。所有操作都级联到Role列表。 Role没有自己的生命周期,无法单独查询。

@Embeddable
public class Role {
    @Id
    @GeneratedValue
    private Long id;
    String name;

    public Role(){}

    public Role(String name) {this.name=name;}

    public String getName(){return name; }

    public void setName(String name) {this.name= name; }
}

您还需要对用户进行一些更改:

@Entity
public class User extends BaseEntity{

    private String username;
    private String password;
    @ElementCollection
    private List<Role> roles;
    private boolean active;
}

如果你想自定义集合表,可以使用@CollectionTable。如果缺少 @CollectionTable 注释,则应用 @CollectionTable 注释元素的默认值。引用文档:https://docs.oracle.com/javaee/7/api/javax/persistence/CollectionTable.html .

关于spring - 使用 @OneToMany 或 @ManyToMany 定位未映射的类 : com. example.soasec.entities.User.roles[com.example.soasec.entities.Role],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69273201/

相关文章:

java - 只允许在 REST API 中使用 PUT 的某些字段(Spring)

java - Android 意外的顶级异常和验证错误

java - Spring 框架到底是干什么用的?

java - 从关系数据库中删除实体时出现问题

java - 卡夫卡给 : "The group member needs to have a valid member id before actually entering a consumer group"

java - 如何在 Spring Boot 应用程序启动时启动 H2 TCP 服务器?

java - 如何在 phpstorm(基于速度)文件模板中将字符串转换为驼峰式大小写?

java - Intellij Idea - Java程序在构建jar后无法正常工作

java - org.springframework.web.HttpMediaTypeNotSupportedException : Content type 'application/json' not supported(Ajax, Spring )

spring-boot - 在 Spring Boot Rest API 中将 Map 用作 @RequestBody 不起作用