Spring数据中的复杂实体映射

时间:2016-11-24 05:49:26

标签: java spring entity-relationship

我有用户和董事会的实体。 他们有ManyToMany关系。这是我的代码,

用户

@Entity
    public class User  extends BaseEntity{

      private String firstName;
      private String lastName;
      @ManyToMany(targetEntity = Board.class)
      private List<Board> boards;



      protected User(){
        super();
      }
    }

董事会

@Entity
    public class Board extends BaseEntity{

      private String name;

      @ManyToMany(targetEntity = User.class)
      private List<User> members;


      protected Board(){
        super();
      }
    }
  

代码在这里工作正常。

现在我还想添加一个用户作为董事会的所有者,并类似地映射用户拥有的董事会数量。

如果我执行以下操作,

@ManyToOne
User owner

和用户

 @OneToMany(mappedBy = "boards_owned", cascade = CascadeType.ALL)
  private List<Board> ownedBoards;

这会引发以下错误。

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: io.soumasish.pingg.models.Board.boards_owned in io.soumasish.pingg.models.User.ownedBoards
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1583) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1081) ~[spring-context-4.3.4.RELEASE.jar:4.3.4.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:856) ~[spring-context-4.3.4.RELEASE.jar:4.3.4.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542) ~[spring-context-4.3.4.RELEASE.jar:4.3.4.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.4.2.RELEASE.jar:1.4.2.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:761) [spring-boot-1.4.2.RELEASE.jar:1.4.2.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:371) [spring-boot-1.4.2.RELEASE.jar:1.4.2.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-1.4.2.RELEASE.jar:1.4.2.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1186) [spring-boot-1.4.2.RELEASE.jar:1.4.2.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1175) [spring-boot-1.4.2.RELEASE.jar:1.4.2.RELEASE]
    at io.soumasish.pingg.Application.main(Application.java:12) [main/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_102]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_102]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_102]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_102]
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147) [idea_rt.jar:na]
Caused by: org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: io.soumasish.pingg.models.Board.boards_owned in io.soumasish.pingg.models.User.ownedBoards
    at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:769) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
    at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:719) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
    at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:54) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1655) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1623) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:278) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:847) ~[hibernate-entitymanager-5.0.11.Final.jar:5.0.11.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:874) ~[hibernate-entitymanager-5.0.11.Final.jar:5.0.11.Final]
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60) ~[spring-orm-4.3.4.RELEASE.jar:4.3.4.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:353) ~[spring-orm-4.3.4.RELEASE.jar:4.3.4.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:373) ~[spring-orm-4.3.4.RELEASE.jar:4.3.4.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:362) ~[spring-orm-4.3.4.RELEASE.jar:4.3.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1642) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1579) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE]
    ... 21 common frames omitted


Process finished with exit code 1

那我怎么能这样做呢。

2 个答案:

答案 0 :(得分:0)

您必须使用@JoinTable(带有中间表USER_BOARD)来创建多对多关系hibernate-many-to-many-annotation-mapping-tutorial

在用户

@ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name="USER_BOARD", 
                joinColumns={@JoinColumn(name="USER_ID")}, 
                inverseJoinColumns={@JoinColumn(name="BOARD_ID")})
    private List<Board> boards= new ArrayList<>(); 

在董事会

@ManyToMany(mappedBy="boards")
    private List<User> users= new ArrayList<>();

已编辑 :很抱歉没有完整阅读该问题

在您的情况下,错误是,您应该从Board User owner提供owner

的mappedBy字段名称
 @OneToMany(mappedBy = "owner", cascade = CascadeType.ALL)
  private List<Board> ownedBoards;

答案 1 :(得分:0)

mappedBy引用未知的目标实体属性:io.soumasish.pingg.models.Board.boards_owned in io.soumasish.pingg.models.User.ownedBoards

您的案例没有使用joinTable。我知道JPA M:1:M关系实体。你使用中间表。

示例图片。

enter image description here

M:M

enter image description here

M:1:M

像这样。

@Entity
@Table(name = "middle")
public class MiddleEntity implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int idx;

    @OneToMany(mappedBy = "middle", cascade = { CascadeType.ALL })
    private List<Company> company;

    @OneToMany(mappedBy = "middle", cascade = { CascadeType.ALL })
    private List<Client> client;    


    // ... setter, getter
}


@Entity(name = "company")
public class Company {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int idx;

    @ManyToOne
    @JoinColumn(name = "middle_id")
    private MiddleEntity middle;

    // ...
}



@Entity(name = "client")
public class Client {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int idx;

    @ManyToOne
    @JoinColumn(name = "middle_id")
    private MiddleEntity middle;

    // ...
}