【问题标题】:JPA Hibernate - Mapping MySQL Composite keys to JPA (Hibernate) entitiesJPA Hibernate - 将 MySQL 组合键映射到 JPA (Hibernate) 实体
【发布时间】:2012-04-06 00:07:57
【问题描述】:

我正在尝试映射下表

CREATE TABLE Person (
    p_id varchar(255) not null,
    p_name varchar(255 not null, 
    p_post_code varchar(12) not null,
    primary key (p_id, p_name),
);

通常当我将实体映射到上表时,我会做这样的事情(对于单列主键):

private     int     p_id;   
private     String  p_name;
private     String  p_post_code;

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="p_id")
public Long getPId() {
    return p_id;
}

public void setPId(int p_id) {
    this.p_id = p_id;
}

@Column(name="p_name")
public String getPname() {
    return p_name;
}

public void setPname(String string) {
    this.p_name = string;
}

@Column(name="p_post_code")
public String getPostCode() {
    return p_post_code;
}

public void setPostCode(String string) {
    this.p_post_code = string;
}   

如果主键是单个列(即 p_id)并且该列的值是在数据库中生成的,则上述方法有效。 我将如何修改上面的内容以映射它,以便 p_id 和 p_name 都是主键。

另外,如果复合键是另一个表中的外键,这将如何工作。

我试图用谷歌搜索一些例子,但我找不到一个简单的例子,而且大多数似乎都在使用基于 XML 的配置。

【问题讨论】:

标签: java mysql hibernate jpa


【解决方案1】:

在 JPA 中使用复合键时,您需要使用嵌入式类作为 id。

在您的情况下,您将有一个人类和一个人的主键类:

@entity
public class Person
{
    @EmbeddedId
    private PersonPK key;

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

    //....
}

@Embeddable
public class PersonPK
{
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="p_id");
    private Long p_id;

    @Column(name="p_name")
    private String p_name;

    public PersonPK(String name)
    {
        p_name = name;
    }

    //....
}

使用类作为人名(因此名称也是外键):

@entity
public class Person
{
    @EmbeddedId
    private PersonPK key;

    @MapsId(value="p_name_id")
    @ManyToOne
    @JoinColumn(name = "p_name_id", referencedColumnName = "id")
    private Name p_name;

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

    //....
}

@Embeddable
public class PersonPK
{
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="p_id");
    private Long p_id;

    @Column(name="p_name_id")
    private Long p_name_id;

    public PersonPK(Name name)
    {
        p_name_id = name.getId();
    }

    //....
}

@Entity
public class Name
{
    @Id
    @GeneratedValue(some generation strategy here)
    @Column(name="id")
    private Long id;

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

    //....
}

【讨论】:

  • “需要使用嵌入式类”不准确。使用@EmbeddedId 是一种可能的解决方案。但是@IdClass 的使用也是如此。只是口味问题。
  • @SteveEbersole 我同意你的看法,但后来我看到了:stackoverflow.com/questions/212350 现在我不确定给定的答案是否适用于生成的值。
  • 偶然发现:stackoverflow.com/questions/4120414 现在我确信我的示例会起作用。不过很有趣。 :-)
猜你喜欢
  • 2011-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-17
  • 2012-07-15
  • 2023-04-03
  • 2016-09-18
相关资源
最近更新 更多