31 java hibernate primary-key hibernate-annotations
我有一个数据库视图,产生一个没有真正主键的结果集.我想使用Hibernate/Persistence将此结果集映射到Java对象.当然,因为没有PK,我无法用任何字段装饰@Id.
在部署时,Hibernate抱怨失踪@Id.我该如何解决这个问题?
Edw*_*ges 26
如果存在使行唯一的列组合,则围绕列组合建模主键类.如果没有,你基本上没有运气 - 但你应该重新审视视图的设计,因为它可能没有意义.
有几种不同的方法:
@Entity
public class RegionalArticle implements Serializable {
@Id
public RegionalArticlePk getPk() { ... }
}
@Embeddable
public class RegionalArticlePk implements Serializable { ... }
Run Code Online (Sandbox Code Playgroud)
要么:
@Entity
public class RegionalArticle implements Serializable {
@EmbeddedId
public RegionalArticlePk getPk() { ... }
}
public class RegionalArticlePk implements Serializable { ... }
Run Code Online (Sandbox Code Playgroud)
详细信息如下: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
与在 Hibernate 中搜索解决方法不同,在数据库视图中添加虚拟 ID 可能更容易。假设我们有包含两列的 PostgreSQL 视图,并且它们都不是唯一的(并且没有主键,因为 Postgres 不允许对视图进行 PK 或任何其他约束)例如。
| employee_id | project_name |
|:------------|:-------------|
| 1 | Stack01 |
| 1 | Jira01 |
| 1 | Github01 |
| 2 | Stack01 |
| 2 | Jira01 |
| 3 | Jira01 |
------------------------------
Run Code Online (Sandbox Code Playgroud)
由以下查询表示:
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
Run Code Online (Sandbox Code Playgroud)
我们可以使用 row_number() 添加虚拟 ID:
SELECT row_number() OVER (ORDER BY subquery.employee_id) AS row_id
Run Code Online (Sandbox Code Playgroud)
就像在这个例子中:
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;
Run Code Online (Sandbox Code Playgroud)
该表将如下所示:
| row_id | employee_id | project_name |
|:------------|:------------|:-------------|
| 1 | 1 | Stack01 |
| 2 | 1 | Jira01 |
| 3 | 1 | Github01 |
| 4 | 2 | Stack01 |
| 5 | 2 | Jira01 |
| 6 | 3 | Jira01 |
-------------------------------------------
Run Code Online (Sandbox Code Playgroud)
现在我们可以在 JPA/Hibernate/Spring Data 中使用 row_id 作为 @Id:
@Id
@Column(name = "row_id")
private Integer id;
Run Code Online (Sandbox Code Playgroud)
就像在这个例子中:
@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.
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
50573 次 |
| 最近记录: |