Вторичные таблицы или OnetoOne ассоциации? - PullRequest
6 голосов
/ 18 августа 2010

Учитывая следующую «модель»:

USER
    Long: PK
    String: firstName
    String: lastName

USER_EXT
    Long: PK
    String: moreInfo
    Date: lastModified

Я пытаюсь найти / создать правильное отображение Hibernate (используя аннотации) так, чтобы при запросе HQL, таком же простом, как «от пользователя», он генерировал следующий SQL:

select firstName, moreInfo from USER, USER_EXT where user.pk = user_ext.pk

Я перепробовал все, от использования @Secondarytable до ассоциации @OneToOne, но не могу заставить его работать.

Лучший результат, который у меня есть, теперь связан с ассоциацией @OneToOne, которая генерирует несколько SQL-запросов, один для выборки строк в USER и для каждой строки в наборе результатов запрос на выборку из USER_EXT.

Это довольно неэффективно.

Есть идеи?

1 Ответ

2 голосов
/ 18 августа 2010

Выбор между OneToOne и Secondarytable каким-то образом зависит от модели объекта (т. Е. Если вы хотите, чтобы объект был для расширения пользователя).Я решил использовать OneToOne ассоциацию и две сущности.

Для User (обратите внимание на использование PrimaryKeyJoinColumn для общего первичного ключа):

@Entity
public class User {

    @Id private Long id;
    private String firstName;
    private String lastName;

    @OneToOne
    @PrimaryKeyJoinColumn
    private UserExt userExt;

    public UserExt getUserExt() {
        return userExt;
    }
    public void setUserExt(UserExt userExt) {
        this.userExt = userExt;
    }
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
}

И UserExt:

@Entity
public class UserExt {

    @Id private Long id;
    private String moreInfo;
    @Temporal(TemporalType.DATE)
    private Date lastModified;
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getMoreInfo() {
        return moreInfo;
    }
    public void setMoreInfo(String moreInfo) {
        this.moreInfo = moreInfo;
    }
    public Date getLastModified() {
        return lastModified;
    }
    public void setLastModified(Date lastModified) {
        this.lastModified = lastModified;
    }   
}

С вышеуказанными сущностями следующий HQL-запрос:

select u.firstName, u.userExt.moreInfo from User u

Создает следующий SQL-запрос:

select
  userx0_.firstName as col_0_0_,
  userextx1_.moreInfo as col_1_0_ 
 from
  User userx0_,
  UserExt userextx1_ 
 where
  userx0_.id=userextx1_.id

Какой ожидаемый результат.

PS: JPAНа самом деле 1.0 обеспечивает плохую поддержку производных идентификаторов (в JPA 2.0 все намного лучше), и вам придется вручную установить Id на UserExt, если только вы не используете специфичный для Hibernate foreign генератор.Подробности смотрите в приведенном ниже вопросе.

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

...