使用Hibernate将实体映射到物化视图

4
我需要将 (PostgreSQL) 的物化视图与 Hibernate 中的 @Entity 进行映射。如果配置了hbm2ddlupdate 值,则Hibernate总是尝试创建新的SQL表,而只有当视图是物化视图时才会发生这种情况,否则(对于非物化视图)它可以正常工作。 映射实体
@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,则会抛出异常。
谢谢您的帮助。
3个回答

3

这不是一个很好的解决方案,但它可以工作。我刚刚创建了一个新视图,它引用了一个物化视图。如果您不需要自动模式生成,则应查看 Vlad Mihalcea的解决方案

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;

1
毕竟也不是那么糟糕。谢谢! - Grzegorz

2

在这种情况下,您不应该使用hibernate.hbm2ddl.auto。实际上,您应该始终优先使用增量数据库脚本,同时使用FlywayDB自动化数据库更新过程。

因为您使用了特定于数据库的物化视图,所以Hibernate模式生成器对您没有任何帮助。因此,您唯一的选择是数据库特定的增量脚本。

您仍然可以针对PostgreSQL和集成测试内存数据库(例如HSQLDB或H2)维护单独的脚本。


当然,在生产中使用验证值。但在这种情况下,验证失败了。你认为将PostgreSQL物化视图映射到@Entity是不可能的吗? - Peter Jurkovic
可以做到。Hibernate已经支持将实体映射到视图超过十年了。但是,即使是用于验证的自动模式生成也无法使用。只需将其替换为增量脚本即可。 - Vlad Mihalcea
是的,谢谢。但我会寻找另一个可能的解决方案(如果有的话),因为hdm2ddl是非常舒适的功能。 - Peter Jurkovic

1

使用@Subselect("SELECT * FROM quasar_evaludated_function")替代@Table


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接