【问题标题】:Hibernate Many-to-Many relationship with an additional tableHibernate 与附加表的多对多关系
【发布时间】:2013-06-03 19:55:27
【问题描述】:

我正在使用 Hibernate,我希望能够创建多对多对多的关系。目前的情况是:-

一个乐队可能在许多场地演出,一个场地可能有很多乐队。

BAND >------< VENUE

这将构成多对多关系,因此我使用连接表,例如:-

BAND ----< BAND_VENUES >---- VENUE

我能够使用休眠或 SQL 来创建它;查看测试用例:-

@Entity
@Table(name = "Band")
public class Band implements Serializable,
{
    @Id
    @GeneratedValue(generator = "bandId" )
    @GenericGenerator(name = "bandId", strategy = "uuid2")
    private String bandId;

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "Band_Venues",
    joinColumns =  
    {
        @JoinColumn(name = "bandId")
    },
    inverseJoinColumns = 
    {
        @JoinColumn(name = "venueId")
    })
}

@Entity
@Table(name = "Venue")
public class Venue implements Serializable
{
    @Id
    @GeneratedValue(generator = "venueId" )
    @GenericGenerator(name = "venueId", strategy = "uuid2")
    private String venueId;
}

这看起来很简单,对我来说很有意义。

如果我使用以下场景添加另一个多对多关系,我会感到困惑。

一个乐队可能会在不同的日期/时间在许多场地演出,所以:-

BAND ----< GIG_DATES >-----< GIG_DATES_VENUES >---- VENUE

我认为这种关系应该是使用休眠的,但我实际上没有“BAND_VENUES”的映射,那么我该如何创建这种关系?

我使用的是注解而不是映射文件

【问题讨论】:

    标签: java sql database hibernate jta


    【解决方案1】:

    在多对多关系获得属性的那一刻,它就不再是关系了。关系在 JPA 中没有属性,实体有。

    这种“与属性的关系”被建模为一个中间实体,它将与原始实体具有多对一的关系,在这种情况下与BandVenue。大致如下:

    @Entity
    @IdClass(GigId.class)
    public class Gig {
        @Id
        @ManyToOne
        private Band band
        @Id
        @ManyToOne
        private Venue venue;
    
    }
    
    public class GigId implements Serializable{
        private String band;
    
        private String venue;
        ...
        //date
    }
    
    public class Band { ..
        @OneToMany(mappedBy = "band")
        private Collection<Gig> gigs;
        ...
    }
    
    public class Venue {..
       @OneToMany(mappedBy = "venue")
       private Collection<Gig> gigs;
       ...
    }
    

    【讨论】:

    • 我明白了,那么日期/时间会成为复合键的一部分吗?否则我假设一个乐队只能在一个场地演奏一次
    • 感谢您的回答,我已经给了 +1,但是 Marcel Stör 的回答是相同的,并且提供了同样多的帮助,因为他首先发布了我将他标记为正确答案:- (
    • 这部分+1:On the moment when many-to-many relationship gets attributes, it is not relationship anymore. Relationships do not have attributes in JPA, entities do.这是他们接受的答案没有的关键部分。
    【解决方案2】:

    不确定这是否是您喜欢听到的,但我的处理方式会略有不同。

    乐队不是在特定日期/时间在场地演奏吗?

    因此,我从概念上“扩展”初始 BAND_VENUES 连接表

    BAND -------- VENUE

    并为其添加时间戳。

    这自然会导致一个新实体GIG 替换(匿名)BAND_VENUES 连接表。它有一个

    • BAND 的多对一关系
    • VENUE 的多对一关系
    • 时间戳
    • ...

    【讨论】:

    • 我明白了,那么日期/时间会成为复合键的一部分吗?否则我假设一个乐队只能在一个场地演奏一次
    • 提供的答案已经解决了我的问题,所以我将其标记为正确答案,因为它是第一个回答的
    • 您最好将新 Gig 实体视为所有其他实体:为其分配一个自动生成的单列 ID。如果需要,可以在其他三个字段上添加唯一约束,但单列自动生成的键更简洁、更高效且更易于使用。这允许更改演出的日期,如果日期是 PK 的一部分,这是不可能的。
    • 是的,这当然更好......我应该在我的评论中包含这个,sry
    【解决方案3】:

    我同意 Marcel 的观点(他打败了我,但我已经写好了)。通过制作一个名为 Performance 的“连接”表,您基本上拥有相同的东西。 (请原谅我的伪代码)大致如下:

    @Entity
    class Band 
    {
       @OneToMany
       Performance performance;
    }
    
    @Entity   
    class Performance
    {  
       @ManyToOne
       Band band;
       @OneToOne (or many to many is sometimes easier to work with)
       Venue Venue;
       Date date;
    }
    
    @Entity
    class Venue {
       String address;
    }
    

    【讨论】:

      猜你喜欢
      • 2011-07-07
      • 2020-05-01
      • 2012-03-25
      • 2011-05-25
      • 1970-01-01
      • 1970-01-01
      • 2011-12-15
      • 1970-01-01
      • 2011-09-01
      相关资源
      最近更新 更多