2012-03-21 4 views
1

Я пытаюсь отобразить следующую таблицуJPA Hibernate - Отображение MySQL Композитные ключи к JPA (Hibernate) субъектам

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 были первичным ключом.

Также, как это работает, если составной ключ является внешним ключом в другой таблице.

Я пытаюсь Google для некоторых примеров, но я не могу найти простой пример, и большинство из них, похоже, использует конфигурацию на основе XML.

+0

Вы можете посмотреть здесь: [stackoverflow] [1]: http://stackoverflow.com/questions/9764204/how-to-create-a-composite-primary-key-hibernate-jpa/9765674#9765674 – Andrey

ответ

1

При использовании составных клавиш с JPA вам необходимо использовать встроенный класс в качестве идентификатора.

В вашем случае будет иметь класс человек и первичный ключ класса для человека:

@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; 

    //.... 
} 
+0

" нужно использовать встроенный класс "неточно. Использование '@ EmbeddedId' - одно из возможных решений. Но так же используется '@ IdClass'. Просто вопрос вкуса. –

+0

@SteveEbersole Я бы согласился с вами, но потом я увидел это: http://stackoverflow.com/questions/212350/ Теперь я не уверен, что данный ответ будет работать с генерируемыми значениями. – siebz0r

+0

Наткнувшись на это: http://stackoverflow.com/questions/4120414/ Теперь я уверен, что мой пример будет работать. Интересно, однако. :-) – siebz0r

Смежные вопросы