web-dev-qa-db-ja.com

@Idなしの休止状態/永続性

真の主キーを持たない結果セットを生成するデータベースビューがあります。 Hibernate/Persistenceを使用してこの結果セットをJavaオブジェクトにマップします。もちろん、PKがないため、@Idでフィールドを装飾できません。

デプロイ時に、Hibernateは欠落している@Idについて文句を言います。どうすればこれを回避できますか?

31
Miguel

行を一意にする列の組み合わせがある場合は、列の組み合わせを中心に主キークラスをモデル化します。ない場合は、基本的に運が悪いのですが、ビューのデザインを再検討する必要があります。

いくつかの異なるアプローチがあります:

@Entity
public class RegionalArticle implements Serializable {

    @Id
    public RegionalArticlePk getPk() { ... }
}

@Embeddable
public class RegionalArticlePk implements Serializable { ... }

または:

@Entity
public class RegionalArticle implements Serializable {

    @EmbeddedId
    public RegionalArticlePk getPk() { ... }
}

public class RegionalArticlePk implements Serializable { ... }

詳細はこちら: http://docs.jboss.org/ejb3/app-server/HibernateAnnotations/reference/en/html_single/index.html#d0e1517

同様の問題を説明する投稿を以下に示します。 http://www.theserverside.com/discussions/thread.tss?thread_id=22638

26

エンティティごとに、次の少なくとも1つを指定する必要があります。

  • 1つ @ Id
  • 複数の@Idおよび@IdClass(複合主キーの場合)
  • @EmbeddedId

それで、複数のフィールドを含む複合主キーを作成できますか?

6
Fortega

Hibernateで回避策を検索する代わりに、データベースビューにダミーIDを追加する方が簡単な場合があります。 2つの列を持つPostgreSQLビューがあり、それらのいずれも一意ではないとします(PostgresではビューにPKまたはその他の制約を設定できないため、主キーはありません)。

| employee_id | project_name |
|:------------|:-------------|
| 1           | Stack01      |
| 1           | Jira01       |
| 1           | Github01     |
| 2           | Stack01      |
| 2           | Jira01       |
| 3           | Jira01       |
------------------------------

これは次のクエリで表されます。

CREATE OR REPLACE VIEW someschema.vw_emp_proj_his AS
    SELECT DISTINCT e.employee_id,
                    pinf.project_name
    FROM someschema.project_info pinf
    JOIN someschema.project_employee pe ON pe.proj_id = pinf.proj_id
    JOIN someschema.employees e ON e.employee_id = pe.emloyee_id

Row_number()を使用してダミーIDを追加できます。

SELECT row_number() OVER (ORDER BY subquery.employee_id) AS row_id

この例のように:

CREATE OR REPLACE VIEW someschema.vw_emp_proj_his AS
SELECT row_number() OVER (ORDER BY subquery.employee_id) AS row_id,
       subquery.employee_id,
       subquery.project_name
FROM
  (SELECT DISTINCT e.employee_id,
                   pinf.project_name
   FROM someschema.project_info pinf
   JOIN someschema.project_employee pe ON pe.proj_id = pinf.proj_id
   JOIN someschema.employees e ON e.employee_id = pe.emloyee_id ) subquery;

そして、テーブルは次のようになります。

| row_id      | employee_id | project_name |
|:------------|:------------|:-------------|
| 1           | 1           | Stack01      |
| 2           | 1           | Jira01       |
| 3           | 1           | Github01     |
| 4           | 2           | Stack01      |
| 5           | 2           | Jira01       |
| 6           | 3           | Jira01       |
-------------------------------------------

JPA/Hibernate/Spring Dataで@Idとしてrow_idを使用できるようになりました。

@Id
@Column(name = "row_id")
private Integer id;

例のように:

@Entity
@Table(schema = "someschema", name = "vw_emp_proj_his")
public class EmployeeProjectHistory {

    @Id
    @Column(name = "row_id")
    private Integer id;

    @Column(name = "employee_id")
    private Integer employeeId;

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

//Getters, setters etc.

}
4
luke

「Id」キーとして2つのキーを持つ例を次に示します。 https://Gist.github.com/3796379

1
rogerdpack

次のように@EmbeddedIdを使用できます。

@EmbeddedId
public Id getId() {
    return id;
}

public void setId(Id id) {
    this.id = id;
}
0
Victoria Serkov

ビューの作成に使用する選択を変更します。

SELECT
   ROWNUM ID, -- or use nextval of some sequence
   -- other columns
FROM
  TABLE

そして、「ID」を主キーとしてマップします。

0
Peter S.

論理的なIDがあるかどうかを確認し、それに応じてマッピング情報を提供できます。 Hibernateは定義された主キーの存在についてデータベースをチェックしません。

0
rudolfson