Jpa 来自不同EntityManagerFactory、PersistentUnit的实体的关系(连接)
我正在开发一个多租户web应用程序 使用的技术堆栈是 SpringWebMVC3.2.x, Spring数据JPA 1.4.3, 日食2.5.1 我需要将所有公共数据(如国家、地区等)保存到单独的单个数据库模式中,将所有租户数据(如用户、历史记录)保存到单个共享数据库模式中(基于鉴别器的模型) 实体模型会是这样的 通用主数据实体-国家Jpa 来自不同EntityManagerFactory、PersistentUnit的实体的关系(连接),jpa,eclipselink,Jpa,Eclipselink,我正在开发一个多租户web应用程序 使用的技术堆栈是 SpringWebMVC3.2.x, Spring数据JPA 1.4.3, 日食2.5.1 我需要将所有公共数据(如国家、地区等)保存到单独的单个数据库模式中,将所有租户数据(如用户、历史记录)保存到单个共享数据库模式中(基于鉴别器的模型) 实体模型会是这样的 通用主数据实体-国家 @Entity @Table (name = "country") public class Country implements Serializable{
@Entity
@Table (name = "country")
public class Country implements Serializable{
@GeneratedValue(generator = "assigned-by-code")
@GenericGenerator(name = "assigned-by-code", strategy = "assigned")
private String isoCode;
private String name;
}
@Entity
@Multitenant
@Table (name = "user")
public class User {
@Id
@Column (name = "username")
private String userName;
@Column (name = "first_name", nullable = false)
private String firstName;
@Column (name = "last_name", nullable = false)
private String lastName;
@Column (name = "password", nullable = false)
private String password;
...
}
租户实体
@Entity
@Table (name = "country")
public class Country implements Serializable{
@GeneratedValue(generator = "assigned-by-code")
@GenericGenerator(name = "assigned-by-code", strategy = "assigned")
private String isoCode;
private String name;
}
@Entity
@Multitenant
@Table (name = "user")
public class User {
@Id
@Column (name = "username")
private String userName;
@Column (name = "first_name", nullable = false)
private String firstName;
@Column (name = "last_name", nullable = false)
private String lastName;
@Column (name = "password", nullable = false)
private String password;
...
}
因此,我通过为MASTER和TENANT设置两个不同的entityManagerFactory来实现上述隔离,如下所示
针对租户
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="raoutingDataSource" />
<property name="persistenceUnitName" value="tenant" />
<property name="jpaVendorAdapter">
<bean
class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
<property name="database" value="MYSQL" />
<property name="generateDdl" value="true" />
<property name="showSql" value="true" />
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.archive.autodetection">${hibernate.archive.autodetection}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
<prop key="SetBigStringTryClob">true</prop>
</props>
</property>
<property name="packagesToScan">
<list>
<value>com.sample.entity</value>
</list>
</property>
<property name="jpaPropertyMap">
<map>
<entry key="eclipselink.weaving" value="false" />
</map>
</property>
</bean>
但在服务器启动时,会出现如下错误:
Caused by: javax.persistence.PersistenceException: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [tenant] failed.
Internal Exception: Exception [EclipseLink-7250] (Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5): org.eclipse.persistence.exceptions.ValidationException
Exception Description: [class com.sample.entity.User] uses a non-entity [class com.sample.master.Country] as target entity in the relationship attribute [field country].
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.createPredeployFailedPersistenceException(EntityManagerSetupImpl.java:1954) [eclipselink-2.5.1.jar:2.5.1.v20130918-f2b9fc5]
请按需要操作,因为我不想将主表复制到每个租户的数据源中,因此我需要将其放在单独的位置。由于租户工厂中不存在国家实体,它无法理解引用。您需要将持久性单元组合成一个,以使引用工作 如果必须将它们分开,EclipseLink支持它所称的复合persistencde单元,允许复合成员之间的关系。这里描述了这一点:
而且似乎是你想要的。这使您可以为租户使用复合持久性单元,而读/写操作则应转到下面的不同持久性单元定义。谢谢Chris,我知道EclipseLink在这种情况下可以帮助我。但是它需要persistence.xml文件才能存在。有没有什么方法可以像上面描述的Spring配置一样配置EclipseLink Composite PesistentUnit及其复合成员?任何一个plz都会对此做出响应@Stackoverflow,请做需要的事情