一尘不染

JPA,外部化列,表或架构名称?

tomcat

我将Spring + Hibernate + Tomcat + Oracle应用程序调整为分布式形式,并需要在JPA批注中自定义模式名称,例如Spring
EL:

@Entity
@Table(name = "LOSS", schema="${app.dataSchema}")
public class Loss { ... }

我像${app.dataSchema}上面的示例一样在注释中寻找占位符的支持。或任何其他可能性…

想法-
具有可以在不重新编译的情况下部署到另一个站点的应用程序,保留了数据库关系/层次结构,但是某些名称已更改,可以通过系统属性,JNDI或部署上下文描述符进行配置。

我看到的一种解决方案- create view在选定的架构中-在实际的架构/表/列与应用程序硬编码名称之间架起桥梁。

但是我希望JPA / Hibernate / Spring有一些用于这种配置的工具…


阅读 227

收藏
2020-06-16

共1个答案

一尘不染

Hibernate具有org.hibernate.cfg.Configuration扫描软件包和读取配置文件的功能。

它使用org.hibernate.cfg.AnnotationBinder.bindClass(...)哪个读取类上的注释。

这些类(8 kLOC)和方法用了很长时间,以至于我不容易阅读它们,因此我不希望将Configuration子类化。

即使注意到所有类和初始化代码都绑定到具体类而没有注入自己的可能性,似乎用当前的Hibernate 4.x架构也无法轻松解决我的任务。

我开始寻找替代方案,并在EBean邮件列表中询问配置的外部化问题,并得到了答案

public class MySchemaNamingConvention
    extends com.avaje.ebean.config.UnderscoreNamingConvention {

@Override
protected TableName getTableNameFromAnnotation(Class<?> beanClass) {
   final Table t = findTableAnnotation(beanClass);
   if (t != null && !isEmpty(t.name())) {
       String catalog = t.catalog();
       String schema = t.schema();
       //////   CUSTOM schema processing code HERE.
       //////   CUSTOM schema processing code HERE.
       //////   CUSTOM schema processing code HERE.
       return new TableName(quoteIdentifiers(catalog),
                            quoteIdentifiers(schema),
                            quoteIdentifiers(t.name()));
     }
     return null;
}

真是太容易了,以至于我跟hibernate打个招呼!

更新
@Xstian。在迁移到Ebean之前,我先设置了默认模式,hibernate.default_schema并广泛使用views和synonyms来控制可访问哪个表(Oracle):

grant select on ANOTHER_SCHEMA.TBL to MY_SCHEMA;

create or replace view MY_SCHEMA.TBL as select * from ANOTHER_SCHEMA.TBL;

create or replace synonym MY_SCHEMA.TBL for ANOTHER_SCHEMA.TBL;

在迁移到视图/同义词期间,我仅遇到数据库约束问题。

如果您使用Oracle-视图上的FK约束不起作用,除非您使用disable novalidate关键字和相同的约束添加到引用的PK:

alter view MY_SCHEMA.XXX add constraint PK_XXX primary key(ID) disable novalidate;

alter table/view MY_SCHEMA.TBL add constraint FK_XXX foreign key (XXX_ID)
  references MY_SCHEMA.XXX (ID) disable novalidate;

而且同义词对Oracle完全不允许FK约束!

似乎Hibernate决定了数据布局,我认为应该切换到更灵活的框架Ebean,但我还要评估sql2ojOOQ

2020-06-16