使用 Hibernate 将实体映射到物化视图
Mapping entity to a materialized view using Hibernate
我需要使用 Hibernate 将 (PostgreSQL) 实体化视图映射到 @Entity
。如果 hbm2ddl
配置为 update
值,Hibernate 总是尝试创建新的 SQL table。只有当视图被物化时才会发生这种情况,否则(对于非物化视图)它可以正常工作。
映射实体
@Entity
@Immutable
@Cache (usage=CacheConcurrencyStrategy.READ_ONLY)
@Table(name = "quasar_evaludated_function")
public class EvaluatedAuditor {
private long id;
private boolean qsAuditor;
// getter setters ...
}
SQL 物化视图
CREATE materialized VIEW quasar_evaludated_function
AS SELECT a.id AS id,
(SELECT Count(code)
FROM quasar_qs_auditor_code code
WHERE code.auditor_id = a.id
AND code.is_granted = TRUE) > 0 AS is_qs_auditor
FROM quasar_auditor a;
日志
ERROR 2015-01-14 21:16:17 SchemaUpdate:execute(line 261) - HHH000388: Unsuccessful: create table quasar_evaludated_function (id int8 not null, is_clinical_expert boolean, is_product_assessor_a boolean, is_product_assessor_r boolean, is_product_specialist boolean, is_qs_auditor boolean, is_responsible_clinician boolean, is_technical_expert boolean, primary key (id))
ERROR 2015-01-14 21:16:17 SchemaUpdate:execute(line 262) - ERROR: relation "quasar_evaludated_function" already exists
如果 hbm2ddl
选项配置为 validate
则抛出异常。
感谢您的帮助。
在这种情况下,您不应该使用 hibernate.hbm2ddl.auto
。实际上,您应该始终喜欢使用 incrementing database scripts while having FlywayDB 自动执行数据库更新过程。
因为您使用特定于数据库的物化视图,休眠模式生成器根本无法帮助您。因此,您唯一的选择是特定于数据库的增量脚本。
您仍然可以为 PostgreSQL 和集成测试内存数据库(例如 HSQLDB 或 H2)维护单独的脚本。
这不是一个很好的解决方案,但它确实有效。我刚刚创建了一个新视图,它引用了一个物化视图。如果您不需要自动生成模式,您应该看到 。
CREATE MATERIALIZED VIEW quasar_evaludated_function_mv AS select
a.id as id,
(select count(f) from quasar_qs_auditor_code f where f.auditor_id = a.id and f.is_granted = true) > 0 as is_qs_auditor,
(select count(f) from quasar_product_assessor_a_code f where f.auditor_id = a.id and f.is_granted = true) > 0 as is_product_assessor_a,
(select count(f) from quasar_product_assessor_r_code f where f.auditor_id = a.id and f.is_granted = true) > 0 as is_product_assessor_r,
(select count(f) from quasar_product_specialist_code f where f.auditor_id = a.id and f.is_granted = true) > 0 as is_product_specialist,
(select count(f) from quasar_technical_expert_code f where f.auditor_id = a.id and f.is_granted = true) > 0 as is_technical_expert,
(select count(f) from quasar_clinical_expert_code f where f.auditor_id = a.id and f.is_granted = true) > 0 as is_clinical_expert,
(select count(f) from quasar_responsible_clinician_code f where f.auditor_id = a.id and f.is_granted = true) > 0 as is_responsible_clinician
from quasar_auditor a;
CREATE VIEW quasar_evaludated_function AS SELECT mv.* from quasar_evaludated_function_mv mv;
而不是 @Table
使用 @Subselect("SELECT * FROM quasar_evaludated_function")
我需要使用 Hibernate 将 (PostgreSQL) 实体化视图映射到 @Entity
。如果 hbm2ddl
配置为 update
值,Hibernate 总是尝试创建新的 SQL table。只有当视图被物化时才会发生这种情况,否则(对于非物化视图)它可以正常工作。
映射实体
@Entity
@Immutable
@Cache (usage=CacheConcurrencyStrategy.READ_ONLY)
@Table(name = "quasar_evaludated_function")
public class EvaluatedAuditor {
private long id;
private boolean qsAuditor;
// getter setters ...
}
SQL 物化视图
CREATE materialized VIEW quasar_evaludated_function
AS SELECT a.id AS id,
(SELECT Count(code)
FROM quasar_qs_auditor_code code
WHERE code.auditor_id = a.id
AND code.is_granted = TRUE) > 0 AS is_qs_auditor
FROM quasar_auditor a;
日志
ERROR 2015-01-14 21:16:17 SchemaUpdate:execute(line 261) - HHH000388: Unsuccessful: create table quasar_evaludated_function (id int8 not null, is_clinical_expert boolean, is_product_assessor_a boolean, is_product_assessor_r boolean, is_product_specialist boolean, is_qs_auditor boolean, is_responsible_clinician boolean, is_technical_expert boolean, primary key (id))
ERROR 2015-01-14 21:16:17 SchemaUpdate:execute(line 262) - ERROR: relation "quasar_evaludated_function" already exists
如果 hbm2ddl
选项配置为 validate
则抛出异常。
感谢您的帮助。
在这种情况下,您不应该使用 hibernate.hbm2ddl.auto
。实际上,您应该始终喜欢使用 incrementing database scripts while having FlywayDB 自动执行数据库更新过程。
因为您使用特定于数据库的物化视图,休眠模式生成器根本无法帮助您。因此,您唯一的选择是特定于数据库的增量脚本。
您仍然可以为 PostgreSQL 和集成测试内存数据库(例如 HSQLDB 或 H2)维护单独的脚本。
这不是一个很好的解决方案,但它确实有效。我刚刚创建了一个新视图,它引用了一个物化视图。如果您不需要自动生成模式,您应该看到
CREATE MATERIALIZED VIEW quasar_evaludated_function_mv AS select
a.id as id,
(select count(f) from quasar_qs_auditor_code f where f.auditor_id = a.id and f.is_granted = true) > 0 as is_qs_auditor,
(select count(f) from quasar_product_assessor_a_code f where f.auditor_id = a.id and f.is_granted = true) > 0 as is_product_assessor_a,
(select count(f) from quasar_product_assessor_r_code f where f.auditor_id = a.id and f.is_granted = true) > 0 as is_product_assessor_r,
(select count(f) from quasar_product_specialist_code f where f.auditor_id = a.id and f.is_granted = true) > 0 as is_product_specialist,
(select count(f) from quasar_technical_expert_code f where f.auditor_id = a.id and f.is_granted = true) > 0 as is_technical_expert,
(select count(f) from quasar_clinical_expert_code f where f.auditor_id = a.id and f.is_granted = true) > 0 as is_clinical_expert,
(select count(f) from quasar_responsible_clinician_code f where f.auditor_id = a.id and f.is_granted = true) > 0 as is_responsible_clinician
from quasar_auditor a;
CREATE VIEW quasar_evaludated_function AS SELECT mv.* from quasar_evaludated_function_mv mv;
而不是 @Table
使用 @Subselect("SELECT * FROM quasar_evaludated_function")