2016-03-04 5 views
2

Этот пример приведен в учебном пособии JBOSS для спящего режима. Ссылка есть: http://docs.jboss.org/hibernate/orm/5.1/userguide/html_single/Hibernate_User_Guide.html#embeddables.ADD CONSTRAINT in Hibernate tutorial

Пример 79. Однонаправленный @OneToMany ассоциация

@Entity(name = "Person") 
public static class Person { 

    @Id 
    @GeneratedValue 
    private Long id; 
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) 
    private List<Phone> phones = new ArrayList<>(); 

    public Person() { 
    } 

    public List<Phone> getPhones() { 
     return phones; 
    } 
} 

@Entity(name = "Phone") 
public static class Phone { 

    @Id 
    @GeneratedValue 
    private Long id; 

    private String number; 

    public Phone() { 
    } 

    public Phone(String number) { 
     this.number = number; 
    } 

    public Long getId() { 
     return id; 
    } 

    public String getNumber() { 
     return number; 
    } 
} 
CREATE TABLE Person (
    id BIGINT NOT NULL , 
    PRIMARY KEY (id) 
) 

CREATE TABLE Person_Phone (
    Person_id BIGINT NOT NULL , 
    phones_id BIGINT NOT NULL 
) 

CREATE TABLE Phone (
    id BIGINT NOT NULL , 
    number VARCHAR(255) , 
    PRIMARY KEY (id) 
) 

ALTER TABLE Person_Phone 
ADD CONSTRAINT UK_9uhc5itwc9h5gcng944pcaslf 
UNIQUE (phones_id) 

ALTER TABLE Person_Phone 
ADD CONSTRAINT FKr38us2n8g5p9rj0b494sd3391 
FOREIGN KEY (phones_id) REFERENCES Phone 

ALTER TABLE Person_Phone 
ADD CONSTRAINT FK2ex4e4p7w1cj310kg2woisjl2 
FOREIGN KEY (Person_id) REFERENCES Person 

Мой вопрос, в этом примере:

1) Почему ADD CONSTRAINT выглядит как машина генерироваться строка, "FKr38us2n8g5p9rj0b494sd3391"? Разве это не должно создаваться вручную с более значимым ограничением?

2) Возможно ли добавление ADD CONSTRAINT в этом случае?

ответ

1

Почему ADD CONSTRAINT выглядит как машина сгенерированный код, «FKr38us2n8g5p9rj0b494sd3391»? Разве это не должно создаваться вручную с помощью более значимого ограничения ?

Ограничение не создается базой данных, конечно. Он генерируется Hibernate.

Это странное имя FKr38us2n8g5p9rj0b494sd3391 создается из-за ограничения длины имен ограничений в некоторых базах данных. Например, в базе данных Oracle длина строки не может превышать 30 символов.

Hibernate генерирует имя ограничения путем объединения имен таблиц и свойств и преобразования результата в MD5, создавая строки, такие как FKr38us2n8g5p9rj0b494sd3391. Этот фрагмент кода от источника Hibernate

/** 
* Hash a constraint name using MD5. Convert the MD5 digest to base 35 
* (full alphanumeric), guaranteeing 
* that the length of the name will always be smaller than the 30 
* character identifier restriction enforced by a few dialects. 
* 
* @param s The name to be hashed. 
* 
* @return String The hashed name. 
*/ 
public String hashedName(String s) { 
    try { 
     MessageDigest md = MessageDigest.getInstance("MD5"); 
     md.reset(); 
     md.update(s.getBytes()); 
     byte[] digest = md.digest(); 
     BigInteger bigInt = new BigInteger(1, digest); 
     // By converting to base 35 (full alphanumeric), we guarantee 
     // that the length of the name will always be smaller than the 30 
     // character identifier restriction enforced by a few dialects. 
     return bigInt.toString(35); 
    } 
    catch (NoSuchAlgorithmException e) { 
     throw new HibernateException("Unable to generate a hashed name!", e); 
    } 
} 

Вы можете создавать свои собственные имена ограничений (уникальный и внешний ключ) с использованием ImplicitNamingStrategy. В качестве примера можно привести Hibernate5NamingStrategy.

Также для указания имен ограничений (в общем случае) вы можете использовать аннотации @ForeignKey и @JoinColumn.

В случае таблицы соединений вы можете использовать аннотацию @JoinTable, как предположил @uditkhare. Но вы должны предоставить гораздо больше информации (это не очень удобно)

@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) 
@JoinTable(name="person_phones", 
    joinColumns = @JoinColumn(name = "f_person_pid", foreignKey = @ForeignKey(
      name = "fk_person_phones_person")), 
    inverseJoinColumns = @JoinColumn(name = "fk_phone", 
      foreignKey = @ForeignKey(name = "fk_person_phones_phone")), 
      uniqueConstraints = @UniqueConstraint(name = "uk_person_phones_phone", 
      columnNames = { "fk_phone" })) 
private List<Phone> phones = new ArrayList<>(); 

ли ADD CONSTRAINT необязательными в этом случае?

Нет. Это не является обязательным. Необходимо моделировать отношение @OneToMany.

+0

Отлично. Спасибо. – user697911

+0

@ user697911 Добро пожаловать. –

0

Да, который генерируется только спящим режимом.

Если вы хотите определить те самостоятельно, вы можете использовать что-то, как показано ниже:

@OneToMany 
@JoinTable([email protected](name="my_unique_key", columnNames={"phones_id"})) 
+0

Вы имеете в виду, что операторы 3 «create table» создаются разработчиками, но «Таблица изменений» добавляется БД. Поэтому в учебнике мне нужно только определение двух классов и создание таблицы, не беспокоясь о «alter table», если я хочу попробовать учебник. Правильно? – user697911

+0

@ user697911 Все сценарии создания схемы генерируются Hibernate, а не базой данных. См. Мой ответ. –

+0

@ v.ladynev прав, я отредактировал свой ответ –