【问题标题】:OneToMany & ManyToOne mapping JPA / HibernateOneToMany & ManyToOne 映射 JPA / Hibernate
【发布时间】:2019-02-24 06:49:15
【问题描述】:

我有两个具有外键关系的表。我试过搜索如何做到这一点,它总是会导致 OneToMany 和 ManyToOne 映射。我有这两张桌子。

用户角色

用户

我正在尝试通过将位置列的值获取到 user_role 表来显示所有用户并显示他们的位置。

这是我的课

用户.java

@Entity
@Table(name="user")
public class User {

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

    ..........

    private UserRole userRole;

    @ManyToOne()
    @JoinColumn(name="role_id")
    public UserRole getUserRole() {
        return userRole;
    }

    public void setUserRole(UserRole userRole) {
        this.userRole = userRole;
    }

    .......
}

UserRole.java

@Entity
@Table(name="user_role")
public class UserRole {

    .......

    private List<User> user;

    @OneToMany(targetEntity=User.class, mappedBy="userRole",cascade=CascadeType.ALL, fetch = FetchType.LAZY)
    public List<User> getUser() {
        return user;
    }

    public void setUser(List<User> user) {
        this.user = user;
    }

    public long getRole_id() {
        return role_id;
    }

    public void setRole_id(long role_id) {
        this.role_id = role_id;
    }

    .........

}

而且我不断收到此错误。

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 javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not determine type for: java.util.List, at table: user_role, for columns: [org.hibernate.mapping.Column(user)]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1699) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:573) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1089) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:859) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:780) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:412) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:333) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1277) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1265) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at com.rtc_insurance.AdminApplication.main(AdminApplication.java:10) [classes/:na]
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not determine type for: java.util.List, at table: user_role, for columns: [org.hibernate.mapping.Column(user)]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:402) ~[spring-orm-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:377) ~[spring-orm-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1758) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1695) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    ... 16 common frames omitted
Caused by: org.hibernate.MappingException: Could not determine type for: java.util.List, at table: user_role, for columns: [org.hibernate.mapping.Column(user)]
    at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:456) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:423) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.mapping.Property.isValid(Property.java:226) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:597) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.mapping.RootClass.validate(RootClass.java:265) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:329) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:461) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:892) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:57) ~[spring-orm-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:390) ~[spring-orm-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    ... 20 common frames omitted

这是我第一次使用 spring,所以我不太熟悉。任何帮助将不胜感激。

【问题讨论】:

标签: hibernate jpa spring-data-jpa one-to-many many-to-one


【解决方案1】:

你能像这样将关系移动到相关对象吗

@ManyToOne()
@JoinColumn(name="role_id", referencedColumnName = "role_id", insertable = false, updatable = false)    
private UserRole userRole;

对 userRole 也是如此

@OneToMany(targetEntity=User.class, mappedBy="userRole",cascade=CascadeType.ALL, fetch = FetchType.LAZY)    
private List<User> user = new ArrayList<>();

更新

jar 文件似乎已损坏。尝试从 .m2\repository 和 mvn clean install

中删除内容

右键单击您的项目,选择 Maven,更新项目,选中强制更新快照/发布。

【讨论】:

  • 我试过了,它仍然给我同样的错误。我还将列名位置更改为role_id。 :(
  • 你能在你的 application.properties 中设置 spring.jpa.generate.ddl-auto=create,让它为你创建表然后让我知道如果仍然看到错误。
  • 我做了,但我使用了 spring.jpa.hibernate.ddl-auto= create。它仍然给我同样的错误。对不起,这是我第一次使用弹簧。现在它给了我这个错误。
  • 扫描失败 [file:/C:/Users/roxan/.m2/repository/org/apache/maven/maven-project/2.2.1/maven-project-2.2.1.jar ] 来自类加载器层次结构 java.util.zip.ZipException:在 java.util.zip.ZipFile.read(Native Method) ~[na:1.8.0_181] 在 java.util.zip.ZipFile 的 LOC 标头(错误签名)无效。访问$1400(ZipFile.java:60) ~[na:1.8.0_181]
  • 删除 .m2\repository 然后运行 ​​mvn clean install
【解决方案2】:

只是一个提示,检查你的实体类并确保你在类声明语句之前包含了@Entity注解。

@Entity
public class MyEntityClass{
 //code
}

然后在 @ManyToMany 或 @OneToMany 关系下使用上述 MyEntityClass 的任何其他实体类上添加以下内容。

@OneToMany(mappedBy="mappingItem", cascade=CascadeType.ALL, orphanRemoval=true)
@JsonIgnore
private List<MyEntityClass> myEntityClassItemList;

这种方法在某种程度上对我有用,可能会有所帮助。

【讨论】:

    【解决方案3】:

    您必须注释 Java 字段而不是 getter:

    @OneToMany(targetEntity=User.class, mappedBy="userRole",cascade=CascadeType.ALL, fetch = FetchType.LAZY)
    private List<User> user;
    

    对于User.class

    @ManyToOne
    @JoinColumn(name="role_id")
    private UserRole userRole;
    

    另外,您是否在user 表中定义了role_id 列?我在截图中看不到这个

    【讨论】:

    • 我试了一下并将列从位置重命名为role_id。 “无法从类加载器层次结构中扫描 [file:/C:/Users/roxan/.m2/repository/org/apache/maven/maven-project/2.2.1/maven-project-2.2.1.jar]”跨度>
    【解决方案4】:

    我可以通过在字段和属性之间混合我的注释映射来重新创建您的异常。 我在您上面描述的问题中看到您注释了字段 Id,然后注释了属性 userRole,如果我这样做,我会得到相同的错误。 我可以通过仅注释属性或字段来修复错误。 这两种模型都有效:

    @Entity
    @Table(name = "USER")
    public class User {
    
    
    private Long id;
    private UserRole userRole;
    String userName;
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long getId() {
        return id;
    }
    
    
    public void setId(Long id) {
        this.id = id;
    }
    
    @Column(name = "USER_NAME")
    public String getUserName() {
        return userName;
    }
    
    public void setUserName(String userName) {
        this.userName = userName;
    }
    
    @ManyToOne()
    @JoinColumn(name="role_id")
    public UserRole getUserRole() {
        return userRole;
    }
    
    public void setUserRole(UserRole userRole) {
        this.userRole = userRole;
    }
    }
    

    这也有效:

    @Entity
    @Table(name = "USER")
    public class User {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    
    @ManyToOne()
    @JoinColumn(name="role_id")
    private UserRole userRole;
    
    
    @Column(name = "USER_NAME")
    String userName;
    
    public Long getId() {
        return id;
    }
    
    public void setId(Long id) {
        this.id = id;
    }
    
    public String getUserName() {
        return userName;
    }
    
    public void setUserName(String userName) {
        this.userName = userName;
    }
    
    public UserRole getUserRole() {
        return userRole;
    }
    
    public void setUserRole(UserRole userRole) {
        this.userRole = userRole;
    }
    }
    

    注释字段的其他模型对象示例

    @Entity
    @Table(name = "USER")
    public class User {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    
    @ManyToOne()
    @JoinColumn(name="role_id")
    private UserRole userRole;
    
    
    @Column(name = "USER_NAME")
    String userName;
    
    public Long getId() {
        return id;
    }
    
    public void setId(Long id) {
        this.id = id;
    }
    
    public String getUserName() {
        return userName;
    }
    
    public void setUserName(String userName) {
        this.userName = userName;
    }
    
    public UserRole getUserRole() {
        return userRole;
    }
    
    public void setUserRole(UserRole userRole) {
        this.userRole = userRole;
    }
    }
    

    测试代码(我添加此代码是因为经常存在混淆,即必须设置双向关系才能使用户和 userRole 保持保存到 UserRole)。

        List<User> users = new ArrayList<>();
    
        User user1 = new User();
        user1.setUserName("user1");
        users.add(user1);
    
        User user2 = new User();
        user2.setUserName("user2");
        users.add(user2);
    
        UserRole userRole = new UserRole();
        userRole.setRoleName("admin");
        //Unidirectional relationship
        user1.setUserRole(userRole);
        user2.setUserRole(userRole);
        //set Bidirectional relationship
        userRole.setUsers(users);
    
        userRole = userRoleRepository.save(userRole);
    
        //Show that the two users and the UserRole persisted
        UserRole result = userRoleRepository.findById(userRole.getId()).get();
        assertEquals(2, result.getUsers().size());
    

    【讨论】:

    • 我不敢相信,但这对我有用。谢谢。
    【解决方案5】:

    你可以这样写一对多的关系: 位置-外键

    public class UserRole {
    .....
    @OneToMany(targetEntity = User.class,cascade =CascadeType.ALL)
    @JoinColumn(name="position",referencedColumnName = "role_id")
    private List<User> users; 
    ......  
    }
    

    【讨论】:

      【解决方案6】:

      创建和映射用户及其角色的另一种简单方法。 定义两个实体类以及关系,它将创建第三个映射表:

      1.角色实体:

          @Entity
          @Table(name = "ROLE")
          @Data
          @AllArgsConstructor
          @NoArgsConstructor
          public class Role {
          
              @Id
              @GeneratedValue(strategy = GenerationType.AUTO)
              private long uuid;
              .
              .
              .
              
          }
      

      2。用户实体:

       @Entity
       @Table(name = "USER")
       @Data
       @AllArgsConstructor
       @NoArgsConstructor
       public class User {
      
          @Id
          @GeneratedValue(strategy = GenerationType.AUTO)
          private long uuid;
          .
          .
          .
          @ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
              @JoinTable(name="user_roles",
                  joinColumns = {@JoinColumn(name="user_id", referencedColumnName="id")},
                  inverseJoinColumns = {@JoinColumn(name="role_id", referencedColumnName="id")}
              )
          private List<Role> roles;
          
          
      }
      

      以上代码生成三个表:

      1. ROLE 2. USER 3. USER_ROLE

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多