如何使用eclipselink在基于多模式的多租户Web应用程序中添加缺失列

时间:2017-02-20 08:55:24

标签: java jpa eclipselink multi-tenant

我正在使用"共享数据库/单独模式"开发多租户网络应用程序。使用java,jpa(eclipselink),mysql的方法。我的持久性文件如下所示:

    <persistence-unit name="GroupBuilderPU" transaction-type="RESOURCE_LOCAL">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
            <exclude-unlisted-classes>false</exclude-unlisted-classes>
            <properties>
                <property name="eclipselink.cache.shared.default" value="false"/>
                <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/?"/>
                <property name="eclipselink.ddl-generation" value="create-or-extend-tables"/>
<--- Here goes other properties definition -->
        </persistence-unit>

现在这是我的EntityMangerFactory和EntityManager:

emfForTenant = Persistence.createEntityManagerFactory("GroupBuilderPU");
EntityManager em = emfForTenant.createEntityManager();
        em.setProperty("eclipselink.tenant-id", schemaNameAsTenantId);

它的工作正常,直到我在任何实体中添加任何新的持久性列。

就像我已经添加了一个新列&#39; String rentalinfo&#39; :

@Entity
@Multitenant(MultitenantType.TABLE_PER_TENANT)
@TenantTableDiscriminator(type = TenantTableDiscriminatorType.SCHEMA, contextProperty = PersistenceUnitProperties.MULTITENANT_PROPERTY_DEFAULT)
public class UserAccount implements Serializable {
...
private String rentalinfo;//Newly added column
...
}

在此之后,以下行给出了错误:

em.createQuery("SELECT ua FROM UserAccount ua").getResultList();

错误是:

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'RENTALINFO' in 'field list'

那么在这种方法中添加新列(扩展表)的解决方案是什么?

1 个答案:

答案 0 :(得分:1)

您收到此异常是因为'RENTALINFO'表中不存在UserAccount列。在正常情况下,设置"create-or-extend-tables"将使EclipseLink向现有表发出ALTER,并添加新列。但是,MultitenantType.TABLE_PER_TENANThttps://wiki.eclipse.org/EclipseLink/DesignDocs/Multi-Tenancy/TablePerTenant

不支持ddl生成
  

不支持:

     
      
  1. 不支持架构生成,因为它需要了解所有租户(架构),并且如果使用每个租户使用架构级别表,则必须在创建表后设置访问配置。
  2.   

所以没有ALTER,你的表没有列。

作为旁注,您可以使用以下持久性属性打开EclipseLink SQL日志记录:

<properties>
    <property name="eclipselink.logging.level" value="ALL"/>
    <property name="eclipselink.logging.level.sql" value="FINE"/>
    <property name="eclipselink.logging.parameters" value="true"/>
</properties>

这样,您可以看到EclipseLink正在执行什么查询(或者在这种情况下,不执行)。