36

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

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

4

9 に答える 9

28

行を一意にする列の組み合わせがある場合は、列の組み合わせに基づいて主キー クラスをモデル化します。そうでない場合は、基本的に運が悪いですが、おそらく意味をなさないため、ビューの設計を再検討する必要があります。

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

@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

于 2009-05-29T13:04:50.283 に答える
7

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

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

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

于 2009-05-29T13:03:30.583 に答える
6

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.

}
于 2017-05-18T14:13:34.260 に答える
1

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

于 2012-09-27T20:46:34.620 に答える
0

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

于 2009-05-29T13:01:26.843 に答える
0

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

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

public void setId(Id id) {
    this.id = id;
}
于 2019-02-26T19:02:19.307 に答える
0

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

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

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

于 2019-02-26T14:57:50.977 に答える
-1

あなたが求めているものとは正確には異なりますが、ここに私が使用するちょっとしたトリックがあります. クエリで「rownum」を選択し、「rownum」をモデルの ID 列として定義します。これにより、事実上、すべての行が Hibernate に固有のものになります。

于 2016-04-06T22:39:26.093 に答える