使用JPA映射多对多关系与属性 [英] Mapping many-to-many relationship with attributes with JPA

查看:126
本文介绍了使用JPA映射多对多关系与属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下实体 - 关系图

  [PERSON](* .. N)------<< ;参与> ------(* .. N)[活动] 
/ \
爱好义务

其中 [PERSON] [ACTIVITY] 是实体, < />< / code>与属性(标志) hobby duty 。这些属性是非排他性的:两者可以是相互独立的真或假。



如何使用JPA(或Hibernate)将此ERD映射到Java对象模型?

  @Entity 
class Person {
Collection< Activity>爱好; //只有hobby = true的活动
Collection< Activity>职务; //只有值=真的
}


@Entity
类活动{
Collection< Person>爱好者; //只有hobby = true的人
Collection< Person>专业人士; //只有人的职责=真正
}


解决方案

<



我在JPA 2.1 / Hibernate 5.1上为我工作。




  • Person实体ID = PERSON_ID

  • 活动ID实体= ACTIVITY_ID

  • 连结表名称= PERSON_ACTIVITY >

      @Entity 
    class Person {

    @ManyToMany
    @JoinTable(name = PERSON_ACTIVITY,
    joinColumns = @ JoinColumn(name =PERSON_ID),
    inverseJoinColumns = @ JoinColumn(name =ACTIVITY_ID))
    @WhereJoinTable(clause =hobby = 1)
    Set< Activity> hobbyActivities;
    $ b @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name =PERSON_ACTIVITY,
    joinColumns = @ JoinColumn(name =PERSON_ID),
    inverseJoinColumns = @ JoinColumn(name =ACTIVITY_ID))
    @WhereJoinTable(clause =duty = 1)
    Set< Activity> dutyActivities;

    $ b

    活动实体

      @Entity 
    class Activity {

    @ManyToMany
    @JoinTable(name = PERSON_ACTIVITY,
    joinColumns = @ JoinColumn(name =ACTIVITY_ID),
    inverseJoinColumns = @ JoinColumn(name =PERSON_ID))
    @WhereJoinTable(clause =hobby = 1 )
    Set< Person> hobbyPeople;
    $ b @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name =PERSON_ACTIVITY,
    joinColumns = @ JoinColumn(name =ACTIVITY_ID),
    inverseJoinColumns = @ JoinColumn(name =PERSON_ID))
    @WhereJoinTable(clause =duty = 1)
    Set< Person> dutyPeople;
    }

    关键点




    • 集合必须在所有情况下显式设置Set


    • 每个实体中的@ManyToMany集合中的一个必须被标记为延迟加载


    • 在进行一些测试时,我发现我必须使用DISTINCT很多次不要得到重复的结果(但这只是我的情况)。



    Consider the following entity-relationship diagram

    [PERSON] (*..N) ------ < is engaged into > ------ (*..N) [ACTIVITY]
                              /          \
                           hobby        duty
    

    where [PERSON] and [ACTIVITY] are entities and <is engaged into> is a many-to-many relationship with attributes (flags) hobby and duty. The attributes are non-exclusive: both can be true or false independent of each other.

    How would one map this ERD to the Java object model shown below using JPA (or Hibernate)?

    @Entity
    class Person {
        Collection<Activity> hobbies;     // only activities where hobby=true
        Collection<Activity> duties;      // only activities where duty=true
    }
    
    
    @Entity
    class Activity{
        Collection<Person> aficionados;   // only people where hobby=true
        Collection<Person> professionals; // only people where duty=true
    }
    

    解决方案

    Really interesting case.

    I made it work for me on JPA 2.1 / Hibernate 5.1.

    Assuming that:

    • Id of Person entity = PERSON_ID
    • Id of Activity entity = ACTIVITY_ID
    • Name of linking table = PERSON_ACTIVITY

    Person entity:

    @Entity
    class Person {
    
        @ManyToMany
        @JoinTable(name="PERSON_ACTIVITY",
                joinColumns=@JoinColumn(name="PERSON_ID"),
                inverseJoinColumns=@JoinColumn(name="ACTIVITY_ID"))
        @WhereJoinTable(clause = "hobby = 1")
        Set<Activity>  hobbyActivities;
    
        @ManyToMany(fetch = FetchType.LAZY)
        @JoinTable(name="PERSON_ACTIVITY",
                joinColumns=@JoinColumn(name="PERSON_ID"),
                inverseJoinColumns=@JoinColumn(name="ACTIVITY_ID"))
        @WhereJoinTable(clause = "duty = 1")
        Set<Activity>  dutyActivities;
    
    }
    

    Activity entity:

    @Entity
    class Activity{
    
        @ManyToMany
        @JoinTable(name="PERSON_ACTIVITY",
                joinColumns=@JoinColumn(name="ACTIVITY_ID"),
                inverseJoinColumns=@JoinColumn(name="PERSON_ID"))
        @WhereJoinTable(clause = "hobby = 1")
        Set<Person>  hobbyPeople;
    
        @ManyToMany(fetch = FetchType.LAZY)
        @JoinTable(name="PERSON_ACTIVITY",
                joinColumns=@JoinColumn(name="ACTIVITY_ID"),
                inverseJoinColumns=@JoinColumn(name="PERSON_ID"))
        @WhereJoinTable(clause = "duty = 1")
        Set<Person>  dutyPeople;
    }
    

    Key points:

    • The collection has to be explicitly a Set in all of the cases

    • One of the @ManyToMany sets in each entity has to be marked as lazy loaded

    • While doing some testing i found that i had to use DISTINCT a lot of times not to get repeating results (but that was only maybe my case).

    这篇关于使用JPA映射多对多关系与属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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