【发布时间】:2016-08-05 10:17:51
【问题描述】:
我目前正在创建一个产品,我的意思是一个应用程序,而不是它拥有的工作,但它的结构可以为不同的客户定制。
在后台使用 spring 可以很容易地更改使用的服务/控制器的实现,我只是重载了 bean。客户端我有angularJS,我可能需要重组模块并提供更多的灵活性,但这也应该很容易。
我真正唯一的问题在于 JPA/Hibernate 实体。
这是我的配置:
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="packagesToScan">
<array>
<value>com.xxx.entity</value>
</array>
</property>
<property name="persistenceUnitName" value="MyPU" />
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
<property name="jpaDialect" ref="jpaDialect" />
<property name="jpaProperties">
<props>
<prop key="hibernate.show_sql">${hibernate.show.sql}</prop>
<prop key="hibernate.format_sql">${hibernate.show.sql}</prop>
<prop key="hibernate.dialect">${database.dialect}</prop>
<prop key="hibernate.hbm2ddl.auto">validate</prop>
<!-- <prop key="hibernate.transaction.factory_class">org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory</prop> -->
</props>
</property>
<!-- <property name="sharedCacheMode" value="ENABLE_SELECTIVE" /> -->
</bean>
现在让我们考虑产品中的以下对象,并针对两个不同的客户进行两次定制:
// let's say this one is the basic one
class People{ String firstName;String lastName;}
// one client want us to add one felds
class PeopleClientOne extends People{String address;}
// another define two type of very different people while having one more field common for them
class People{String firstName; String lastName;String anotherField;}
class PeopleOneClientTwo extends People{...}
class PeopleTwoClientTwo extends People{...}
所以我的问题是考虑到以下限制,处理这个问题的最佳方法是什么:
- 没有完整的抽象数据库模型(比如有一张大实体表和一张大属性表)。
- 我使用的是 jackson,所以当我有继承时,我必须注释/更改超类的注释。
- JPA/Jackson 注释在同一个类上,我不想尽可能重复我的模型的类并保持集中。
这是我的想法:
可扩展属性映射:
- 为每个支持此功能的项目类型再添加一个表。
- 数据库可读性较差
- 无法在数据库中应用任何约束。
背书的用法:
- 重写同包同名的实体,放到endorsed文件夹中,当然只能添加新的字段。
- 数据库仍然可读且干净
- 一般来说,不推荐使用 endorsed,但它是可用的,因此值得。
请注意,我目前正在使用 hibernate4,但如果需要,我可以升级到 5。如果您的解决方案使用注释而不是 XML,我可能会在稍后而不是今天切换到注释。
欢迎任何替代贡献,即使它不符合我的要求。
【问题讨论】:
标签: java spring hibernate maven jpa