【问题标题】:JPA Annotations - how to merge two fields into one column for a join table?JPA Annotations - 如何将两个字段合并为一个连接表的一列?
【发布时间】:2017-10-13 00:06:36
【问题描述】:

所以我有两个课程,一个路线和一个巴士站。一条路线“使用”两个 BusStop 对象,一个作为起点,一个作为目的地。我需要通过连接表“使用”映射这种关系。

此连接表不需要区分 BusStop 是用于起点还是终点。基本上我只需要 start 和 destination 成为这个连接表中的一列(允许重复),这样我就可以获得哪些路线使用哪些站点的完整映射。

这是我的设置方式(假设有 getter 和 setter):

public class Route {
    @Id
    private String number;

    @Column(nullable = false)
    private int frequency;

    @ManyToOne
    @JoinTable(
        name = "Uses",
        joinColumns = @JoinColumn(name = "number"),
        inverseJoinColumns = @JoinColumn(name = "id")
    )
    private BusStop start;

    @ManyToOne
    @JoinTable(
        name = "Uses",
        joinColumns = @JoinColumn(name = "number"),
        inverseJoinColumns = @JoinColumn(name = "id")
    )
    private BusStop destination;
    ...
}

public class BusStop {
    @Id
    private int id;

    @Column(nullable = false)
    private String description;

    @OneToMany
    @JoinTable(
        name = "Uses",
        joinColumns = @JoinColumn(name = "id"),
        inverseJoinColumns = @JoinColumn(name = "number")
    )
    private Set<Route> routes;
    ...
}

现在我遇到的问题是,这会产生一个“使用”表,该表只有每个 Route id 之一,尽管它成功地保留了重复的停止 id。我假设它与我尝试在 Route 类中创建两个“使用”表有关?

那么正确的方法究竟是怎样做的呢?

【问题讨论】:

  • 您不能,因为您随后将无法知道它代表哪个 FK(起点或终点)。假设您创建了一个 BusStop,然后向其添加一个 Route(因为 BusStop OWNS 关系)...... Route 如何知道它是开始/目的地?数据库中没有信息知道这一点。如果要检索 Route,则转到连接表,但无法知道它的起点和终点。
  • 如果我在巴士站有两套路线怎么样?传入和传出?我还认为 Route 应该拥有关系?无论如何,谢谢,我可能很快就会放弃连接表
  • 2套是标准的做法,是的
  • 那么,如果我确实有两组 Route,我能否让这个“Uses”连接表更好地工作?如果是这样,怎么做?我目前遇到的问题是每条路线只输入一站
  • 一如既往“这一切都取决于”。一条路线真的应该有多个停靠点,按顺序(即路线中的列表),而不仅仅是一个“开始”和“目的地”......因为公共汽车在它们之间的某个地方......但那部分可能是在您的系统中没有任何价值,只有您自己知道。回到您的问题,用 Java 术语来说,一个 Set 通常可以在其中包含一个特定的对象 ONCE,而 List 或 Multiset 可以有重复项。

标签: java mysql hibernate jpa jdbc


【解决方案1】:

我会采用更清洁的方式来做到这一点。

这是我的实体。

package com.ansh.entity;

import lombok.Getter;
import lombok.Setter;

import javax.persistence.*;

@Entity
@Table(name = "routes")
@Getter @Setter
public class Route {

    @Id
    @Column(name = "number")
    private String number;

    @Column(name = "frequency", nullable = false)
    private int frequency;

    @ManyToOne
    @JoinColumn(name = "start_id")
    private BusStop start;

    @ManyToOne
    @JoinColumn(name = "destination_id")
    private BusStop destination;
}

与

package com.ansh.entity;

import com.google.common.collect.Sets;
import lombok.Getter;
import lombok.Setter;

import javax.persistence.*;
import java.util.Set;

@Entity
@Table(name = "bus_stops")
@Getter @Setter
public class BusStop {

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

    @Column(name = "description", nullable = false)
    private String description;

    @OneToMany(mappedBy = "start")
    private Set<Route> outgoingRoutes = Sets.newHashSet();

    @OneToMany(mappedBy = "destination")
    private Set<Route> incomingRoutes = Sets.newHashSet();

    public Set<Route> getRoutes() {
        return Sets.union(outgoingRoutes, incomingRoutes);
    }
}

【讨论】:

  • 谢谢,我知道这样做,我可能会求助于它.. 但这项工作是为了分配,我们被特别要求创建一个“使用”连接表。有没有办法让它工作?
  • 你能解释一下巴士站与路线的关系吗?它是OneToMany是什么方式?一对多,其中 BusStop 是源或目标或两者。
  • BusStop to Route 是 OneToMany,因为许多路线都使用一个 BusStop,至少我是这么想的。我想它可以被认为是 ManyToMany 但这意味着在 Route 类中合并起点和终点,我不能这样做
猜你喜欢
  • 2014-11-11
  • 2017-10-06
  • 1970-01-01
  • 1970-01-01
  • 2021-11-14
  • 2016-09-17
  • 1970-01-01
  • 1970-01-01
  • 2014-04-01
相关资源
最近更新 更多