【问题标题】:Use of @OneToMany or @ManyToMany targeting an unmapped class: com.example.soasec.entities.User.roles[com.example.soasec.entities.Role]使用@OneToMany 或@ManyToMany 定位未映射的类:com.example.soasec.entities.User.roles[com.example.soasec.entities.Role]
【发布时间】:2021-11-15 06:28:53
【问题描述】:

我正在尝试使用 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&lt;Role&gt; 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 boot 版本:2.5.4

【问题讨论】:

  • 你能发布你的 Role.java 吗?
  • 好的,添加了。

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


【解决方案1】:

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

1) 将Role 设为实体

@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) 使Role 可嵌入

在这种情况下,元素完全归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; }
}

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

@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.

【讨论】:

  • 在这种情况下,如果我的回答有帮助,请考虑支持和/或接受它作为答案,以便其他人可以轻松了解如何解决类似问题。谢谢! ;)
  • 第一个有效,但我还必须在 Role() {} 之前添加“public”,否则会出错
  • 当然,我只是复制了你所拥有的,但错过了。我已经编辑了我的答案。
【解决方案2】:

您需要在 Role.java 中声明user 属性,并带有@ManyToOne 注释:

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

    @ManyToOne
    public User user;

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

在 User.java 中,将:@OneToMany(fetch = FetchType.EAGER, cascade=CascadeType.ALL) 替换为 @OneToMany(mappedBy = "user")

【讨论】:

  • 我试过了,但我得到了同样的错误。在“@OneToMany(mappedBy=“user”)”行的 User.java 类中,“user”字以红色突出显示并随着光标移动,我收到消息:找不到反向属性。
  • 您可以尝试在 Role 类的顶部添加 @Entity 注释吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-24
  • 2016-08-25
  • 1970-01-01
相关资源
最近更新 更多