【问题标题】:Mapping JPA Composite Foreign Key映射 JPA 复合外键
【发布时间】:2017-02-21 07:53:27
【问题描述】:

我是 JPA 的新手,想用这种关系创建一个数据库:

|Participant|
|id : INT (PK) | id_event : INT (PK, FK) |

|Event|
|id : INT (PK) |

我完全迷失了,几乎不知道我找到的示例的语法:/

但我知道我需要创建另一个类来包含两个 PK,这导致另一个问题:这个类可以是内部类(出于优化目的)吗?

我希望我没有要求太多,但我真的很想得到它。

【问题讨论】:

  • 参与者和事件有ManyToMany关系?然后您需要另一个实体,而这个新实体需要将这两个 ID 作为复合主键包含在内。

标签: java jpa


【解决方案1】:

对于 OneToMany 关系,您需要以下实体和表:

  • 参与者
  • 事件

Event 实体很简单:

@Entity
public class Event {
    @Id
    private Long id;

    // fields, constructors, getters, setters
}

实体Participant 必须持有复合键(也就是PK 的两个部分),因此,每个Participant 只与一个事件链接一次。

@Entity
public class Participant {
    @EmbeddedId
    private EventParticipantPK id;

    @OneToMany(fetch = FetchType.LAZY)
    private List<Event> events;

    // fields, constructors, getters, setters
}

复合键被声明为EmbeddedId

EventParticipantPK 应该是这样的:

@Embeddable
public class EventParticipantPK {
    @Column (name = "PARTICIPANT_ID")
    private Long participantId;

    @Column (name = "EVENT_ID")
    private Long eventId;

    // fields, constructors, getters, setters
}

我希望这会有所帮助。

【讨论】:

    【解决方案2】:

    您的实体可能是这样的:

    @Entity
    public class Participant {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        @OneToMany(fetch = FetchType.LAZY)    // or any other relation
        private List<Event> events;
    
        // fields, constructors, getters, setters
    }
    
    @Entity
    public class Event {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        // fields, constructors, getters, setters
    }
    

    在这种情况下,JPA 将使用以下查询创建 3 个表(SQL 方言因数据库而异,在这种情况下我使用 H2 数据库):

    CREATE TABLE Event (
      id bigint GENERATED BY DEFAULT AS IDENTITY,
      PRIMARY KEY (id)
    );
    
    CREATE TABLE Participant (
      id bigint GENERATED BY DEFAULT AS IDENTITY,
      PRIMARY KEY (id)
    );
    
    CREATE TABLE Participant_Event (
      Participant_id bigint NOT NULL,
      events_id      bigint NOT NULL
    )
    

    Participant_Event 自动创建连接表以链接参与者和事件。

    这是理解JPA entity relations的一个很好的例子。

    【讨论】:

    • 感谢您的帮助,但它对我说 The type of field "x.x.x.x.Participant.event" isn't supported by declared persistence strategy "OneToMany". Please choose a different strategy. :(
    • 请再试一次,我更新了答案。但实际上我不知道你必须使用什么关系,这取决于你的目标和要求。您可以阅读文章并做出决定。另一个很好的插图教程是JPA - Entity Relationships
    • 嗯.. 它说"x.x.x.x.Participant.events" declared that it is mapped by "participant", but that is a not a field of the related type. 所以我尝试使用 id 但后来它说Collection field "x.x.x.x.Participant.events" declares that it is mapped by "x.x.x.x.Event.id", but this is not a valid inverse relation. 我完全迷路了,我不得不承认...跨度>
    • 请不要生气,我删除了映射并添加了将创建哪些表的描述,请再看一遍,现在可以了。
    • 好吧,这似乎真的很接近,只是它在另一行写了 id ^^ 无论如何我会更深入地研究它,但这似乎是解决我的问题的正确方法。谢谢!
    猜你喜欢
    • 2019-04-22
    • 2011-03-20
    • 2021-09-19
    • 2017-01-30
    • 1970-01-01
    • 2021-07-01
    • 1970-01-01
    • 2016-09-18
    • 1970-01-01
    相关资源
    最近更新 更多