使用JPA设置一个对多个桌面的桌面 [英] Setting up a One To ManyJoins Against a Bridge Table using JPA

查看:77
本文介绍了使用JPA设置一个对多个桌面的桌面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我在MySQL 5数据库中有以下预先存在的表:




  • 应用

  • 用户

  • User_App_Bridge

    这些关系被映射到App和User之间的User_App_Bridge表(正如名字所暗示的那样,是一个桥梁),作为一对多基数。

    ER图:

    用户------ User_App_Bridge ------应用程序

    p> 1用户与User_App_Bridge表中的许多应用程序相关联。



    1 App与User_App_Bridge表中的许多用户相关联。



    User_App_Bridge表的DDL:

      CREATE TABLE`User_App_Bridge`(
    `User_App_Bridge_Id` int(11)NOT NULL AUTO_INCREMENT,
    `User_Id` int(11)NOT NULL,
    `App_Id` int(11)NOT NULL,
    PRIMARY KEY(`User_App_Bridge_Id`),
    KEY`App_Id`(`App_Id`),
    KEY`User_Id`(`User_Id`),
    CONSTRAINT`user_app_bridge_ibfk_1` FOREIGN KEY(`App_Id`)REFERENCES`App`(`App_Id`)
    )ENGINE = InnoDB DEFAULT CHARSET = utf8;

    假设我有以下映射到这些表的JPA注释类:

      @Entity 
    公共类应用程序{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name =App_Id)
    私人长appId;

    @OneToMany
    @JoinTable

    name =UserAppBridge,
    joinColumns = {@JoinColumn(name =App_Id,referencedColumnName = {@JoinColumn(name =User_Id,referencedColumnName =User_Id)}

    private List< User>用户;

    @Column(name =App_Name)
    private String appName;

    // Getters& Setter方法


    实体
    公共类用户
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column (name =User_Id)
    private long userId;

    @OneToMany
    @JoinTable

    name =UserAppBridge,
    joinColumns = {@JoinColumn(name =User_Id,referencedColumnName = User_Id)},
    inverseJoinColumns = {@JoinColumn(name =App_Id,referencedColumnName =App_Id,unique = true)}

    private List< App>应用;

    @Column(name =User_Name)
    private String userName;

    // Getters& Setter方法

    $ b $ @Entity
    public class UserAppBridge {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name =User_App_Bridge_Id)
    私人长userAppBridgeId;

    @Column(name =User_Id)
    private long userId;

    @Column(name =App_Id)
    private long appId;

    // Getters& Setter方法

    code $


    问题:


    1. 这是(@JoinTable中的块)是用UserAppBridge为User和App实现一对多映射的正确方法吗?


    2. 在@JoinTable中,列&参考列名被分配给SQL值(例如,name =User_Id,referencedColumnName =User_Id)
      或者它应该是Java引用名称(例如name =userId,referencedColumnName =userId)?

    3. 里面的inverseJoinColumns代码为黑色,是unique = true必需的(它是什么)?



  • 我需要在UserAppBridge类中做任何其他的事情(用于连接到应用程序和用户)感谢您花时间阅读本文...

    解决方案

    您的问题的答案:

    1.不,它不是。您需要在User和UserAppBridge之间创建oneToMany映射,并在App和UserAppBridge之间创建oneToMany映射。这里是代码:

    在用户实体中:

      @OneToMany (mappedBy =user)
    private设置< UserAppBridge> userAppBridgeSet;

    在App实体中:

      @OneToMany(mappedBy =app)
    private设置< UserAppBridge> userAppBridgeSet;

    在UserAppBridge实体中:

      @Entity 
    @IdClass(UserAppBridgeId.class)
    public class UserAppBridge {

    @Id
    @Column(name =User_App_Bridge_Id )
    私人长userAppBridgeId;

    @Id
    @Column(name =User_Id)
    private long userId;

    @Id
    @Column(name =App_Id)
    private long appId;

    @ManyToOne
    @PrimaryKeyJoinColumn(name =User_Id,referencedColumnName =User_Id)
    私人用户用户;

    @ManyToOne
    @PrimaryKeyJoinColumn(name =App_Id,referencedColumnName =App_Id)
    私人App应用;

    // Getters& SetApp方法
    }

    在UserAppBridgeId类中:

      public class UserAppBridgeId {

    private long userAppBridgeId;
    private int userId;
    private int appId;

    // Getters& Setter方法
    }

    有关如何创建高级manyToMany关系的更多信息,请参阅< wiki链接


    1. 它应该是一个SQL名称


    2. 使用unique = true ,没有unique = true,它会是manyToMany。



    3. 说明:
      让我们有以下一段代码:

        @OneToMany 
      @JoinTable {
      //这里应该是表名和而不是实体名称
      name =User_App_Bridge,
      joinColumns = {@JoinColumn(name =User_Id,referencedColumnName =User_Id)},
      inverseJoinColumns = {@JoinColumn(name = App_Id,referencedColumnName =App_Id,unique = true)}
      }
      private List< App>应用;

      如果存在unique = true属性,则映射表可以只有唯一的App_id相同的App_id在映射表中不会多次出现一次),而它可以具有任何User_id(相同的User_id可以在映射表中出现多次)。这意味着,一个User_id可能已经分配了更多的App_id,而一个App_id可能只分配了一个User_id。因此你强制一对多关系。


      1. 是的,您确实如此。如答案1所示,您必须为UserAppBridge实体创建一个Id类,并为用户和应用程序实体添加一个映射


      Am new to JPA...

      I have the following preexisting tables inside a MySQL 5 database:

      • App
      • User
      • User_App_Bridge

      The relationship(s) are mapped to the User_App_Bridge table (as the name implies, a bridge) amongst App and User as a One to Many cardinality.

      The E-R diagram:

      User ------ User_App_Bridge------ App

      1 User is associated with many apps inside the User_App_Bridge table.

      1 App is associated with many users inside the User_App_Bridge table.

      The DDL for the User_App_Bridge table:

      CREATE TABLE `User_App_Bridge` (
          `User_App_Bridge_Id` int(11) NOT NULL AUTO_INCREMENT,
          `User_Id` int(11) NOT NULL,
          `App_Id` int(11) NOT NULL,
          PRIMARY KEY (`User_App_Bridge_Id`),
          KEY `App_Id` (`App_Id`),
          KEY `User_Id` (`User_Id`),
          CONSTRAINT `user_app_bridge_ibfk_1` FOREIGN KEY (`App_Id`) REFERENCES `App` (`App_Id`)
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
      

      Lets say that I have the following JPA Annotated Classes which are mapped to these tables:

      @Entity
      public class App {
          @Id
          @GeneratedValue(strategy = GenerationType.AUTO)
          @Column(name = "App_Id")
          private long appId;
      
          @OneToMany
          @JoinTable
          (
              name = "UserAppBridge",
              joinColumns = { @JoinColumn(name="App_Id", referencedColumnName = "App_Id") },
              inverseJoinColumns = { @JoinColumn(name="User_Id", referencedColumnName = "User_Id") }
          )
          private List<User> users;
      
          @Column(name = "App_Name")
          private String appName;
      
          // Getters & Setter methods
      }
      
      @Entity
      public class User {
          @Id
          @GeneratedValue(strategy = GenerationType.AUTO)
          @Column(name = "User_Id")
          private long userId;
      
          @OneToMany
          @JoinTable
          (   
             name = "UserAppBridge",
             joinColumns = { @JoinColumn(name="User_Id", referencedColumnName = "User_Id") },
             inverseJoinColumns = { @JoinColumn(name="App_Id", referencedColumnName = "App_Id", unique = true) }
          )
          private List<App> apps;
      
          @Column(name = "User_Name")
          private String userName;
      
          // Getters & Setter methods
      }
      
      @Entity
      public class UserAppBridge {
      
          @Id
          @GeneratedValue(strategy = GenerationType.AUTO)
          @Column(name = "User_App_Bridge_Id")
          private long userAppBridgeId;
      
          @Column(name = "User_Id")
          private long userId;
      
          @Column(name = "App_Id")
          private long appId;
      
          // Getters & Setter methods
      }
      

      Question(s):

      1. Is this (the block inside the @JoinTable) the correct way to do the one to many mapping for User and App entites with the UserAppBridge?

      2. Inside the @JoinTable should the column & referencedColumnName be assigned to the SQL value (e.g. name="User_Id" , referencedColumnName = "User_Id") or should it be the Java reference name (e.g. name="userId" , referencedColumnName = "userId")?

      3. Inside the inverseJoinColumns code black, is the unique = true necessary (what is it for)?

      4. Do I need to do anything else inside the UserAppBridge class (for connecting to App and User)?

      Thank you for taking the time to read this...

      解决方案

      The answers for your questions:

      1.No, it is not. You need to create a oneToMany mapping between User and UserAppBridge, and oneToMany mapping between App and UserAppBridge. Here is the code:

      In User entity:

          @OneToMany(mappedBy = "user")
          private Set<UserAppBridge> userAppBridgeSet;
      

      In App entity:

          @OneToMany(mappedBy = "app")
          private Set<UserAppBridge> userAppBridgeSet;
      

      In UserAppBridge entity:

          @Entity
          @IdClass(UserAppBridgeId.class)
          public class UserAppBridge{
      
              @Id
              @Column(name = "User_App_Bridge_Id")             
              private long userAppBridgeId;
      
              @Id
              @Column(name = "User_Id")
              private long userId;
      
              @Id
              @Column(name = "App_Id")
              private long appId;
      
              @ManyToOne
              @PrimaryKeyJoinColumn(name="User_Id", referencedColumnName="User_Id")
              private User user;
      
              @ManyToOne  
              @PrimaryKeyJoinColumn(name="App_Id", referencedColumnName="App_Id")  
              private App app;
      
              // Getters & Setter methods
          }
      

      In UserAppBridgeId class:

          public class UserAppBridgeId{
      
              private long userAppBridgeId;
              private int userId;
              private int appId;  
      
              // Getters & Setter methods 
          }
      

      For more information on how to create advanced manyToMany relationship please see a wiki link

      1. It should be an SQL names

      2. With "unique=true" you are forcing a oneToMany relationship, without a "unique=true" it would be manyToMany.

      Explanation: Lets have a following piece of code:

          @OneToMany
          @JoinTable{
              //Here should be the table name and not the entity name
              name = "User_App_Bridge",
              joinColumns = { @JoinColumn(name="User_Id", referencedColumnName = "User_Id") }, 
              inverseJoinColumns = { @JoinColumn(name="App_Id", referencedColumnName = "App_Id", unique = true) }
          }
          private List<App> apps;
      

      if there is a "unique=true" attribute, your mapping table can have only unique App_id (the same App_id can not occure more then once in mapping table), while it can have any User_id (same User_id can occur more then once in mapping table). What this means, is that one User_id may have assigned more App_id, while a single App_id may have assigned only one User_id. Hence you force a oneToMany relationship.

      1. Yes, you do. As shown in answer 1 , you will have to create an Id class for UserAppBridge entity and also add a mapping for User and App entities

      这篇关于使用JPA设置一个对多个桌面的桌面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆