我们目前的开发基于多租户中的鉴别器模型。以下是我们目前正在使用的技术堆栈,
我们通过在每个表中分别保留一列来维护租户id。创建会话时租户id筛选器。
示例模型类。
@Entity
@FilterDef(name = "tenantFilter", parameters = @ParamDef(name = "tenantIdParam", type = "string"))
@Filters(@Filter(name = "tenantFilter", condition = "tenant_id = :tenantIdParam"))
@Table(name = "assessment")
public class Assessment implements java.io.Serializable, Comparable<Assessment> {
private static final long serialVersionUID = -2231966582754667029L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", unique = true, nullable = false)
private Long id;
@Column(name = "tenant_id", nullable = false, updatable = false)
private String tenantId;
// rest of the code...
}
这是会话工厂的配置
<!-- create database connection pool -->
<bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driverClassName}" />
<property name="jdbcUrl" value="jdbc:mysql://${jdbc.host}:3306/${jdbc.database}?createDatabaseIfNotExist=true&autoReconnect=true&useUnicode=true&connectionCollation=utf8_general_ci&characterEncoding=UTF-8" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="idleConnectionTestPeriodInMinutes" value="60"/>
<property name="idleMaxAgeInMinutes" value="240"/>
<property name="maxConnectionsPerPartition" value="30"/>
<property name="minConnectionsPerPartition" value="10"/>
<property name="partitionCount" value="3"/>
<property name="acquireIncrement" value="5"/>
<property name="statementsCacheSize" value="100"/>
<property name="releaseHelperThreads" value="3"/>
</bean>
<!-- Hibernate SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="lk.gov.elg.orm.model"/>
<property name="hibernateProperties">
<value>
hibernate.dialect=${hibernate.dialect}
hibernate.hbm2ddl.auto=update
</value>
</property>
</bean>
<bean id="tenantBasedSessionFactory" class="lk.gov.elg.orm.dao.impl.TenantBasedSessionFactoryImpl">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
租户基础会话工厂
public class TenantBasedSessionFactoryImpl implements TenantBasedSessionFactory {
private SessionFactory sessionFactory;
@Override
public Session getTenantBasedSession(Object tenantId) {
Session session = sessionFactory.openSession();
session.enableFilter("tenantFilter").setParameter("tenantIdParam", tenantId);
return session;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public Session getAllTenantBasedSession() {
Session session = sessionFactory.openSession();
return session;
}
}
示例服务类
@Service("assessmentService")
public class AssessmentServiceImpl implements AssessmentService {
@Autowired
private AssessmentDao assessmentDao;
public Long saveAssessment(Assessment assessment, Object tenantId) {
return assessmentDao.saveAssessment(assessment, tenantId);
}
}
示例DAO类
@Repository("assessmentDao")
public class AssessmentDaoImpl implements AssessmentDao {
@Autowired
private TenantBasedSessionFactory tenantBasedSessionFactory;
public Long saveAssessment(Assessment assessment, Object tenantId) {
Session session = tenantBasedSessionFactory.getTenantBasedSession(tenantId);
try {
session.beginTransaction();
session.save(assessment);
session.getTransaction().commit();
return assessment.getId();
} catch (HibernateException e) {
logger.error("Error in persist assessment:", e);
session.getTransaction().rollback();
return null;
} finally {
session.close();
}
}
}
我想知道有没有一种方法可以通过这个数据库事务鉴别器模型获得spring事务支持?另一件事是,我想知道将事务处理交给spring而不是由我们自己来处理是否有任何好处?
提前谢谢。
我也有类似的问题,我使用aspect而不是定制sessionfactory来解决它,所以我可以利用注释驱动的事务支持
下面的代码是用于注释@Tennant
的方面
@Aspect
public class TennantAspect {
@Autowired
private SessionFactory sessionFactory;
@Around("@annotation(Tennant)")
public Object enableClientFilter(ProceedingJoinPoint pjp) throws Throwable {
Object obj;
boolean isDAO=(pjp.getTarget() instanceof BaseDAO<?,?>);
try {
if(isDAO){
Authentication auth=SecurityContextHolder.getContext().getAuthentication();
if(auth!=null){
User user=(User) auth.getPrincipal();
this.sessionFactory.getCurrentSession().enableFilter("clientFilter").setParameter("clientId", user.getClientId());
}
}
obj=pjp.proceed();
}finally {
if(isDAO)
this.sessionFactory.getCurrentSession().disableFilter("clientFilter");
}
return obj;
}
}
希望这能解决你的问题。
或者,您也可以通过Hibernate查看租赁支持
http://docs.jboss.org/hibernate/orm/4.1/devguide/en-US/html/ch16.htmlhttps://github.com/mariofts/spring-multitenancy
null 如何实现:Spring Data JPA不支持全局筛选器,所以我需要添加定制Spring Data JPA存储库,该存储库可以反过来为基于鉴别器的解决方案应用全局筛选器? 到底有没有可能用Spring Data JPA+Hibernate 3实现我的需求?
我已经在web上阅读了几篇关于多租户(针对SaaS应用程序中的不同客户端)的文章(即这个和那个)。一旦您决定采用基于鉴别器的方法,hibernate文档声明,版本4不支持这种方法,但将在版本5中提供。 尽管如此,您可能会找到几篇关于为此目的使用hibernate过滤器的文章(即这篇和那篇)。 我想知道,如果基于过滤器的解决方案可以的话,为什么在版本5中会有一些特殊的实现呢。因此:基于过滤器的解决方
我有一个JPA应用程序正在运行,现在我想支持多租户。我喜欢使用XML而不是注释。 我有两个orm。从持久性引用的xml。xml。 我喜欢对所有实体使用相同的多租户配置:单个表,鉴别器列是tenantUserId,上下文属性是tenant。用户ID。 根据:https://wiki.eclipse.org/EclipseLink/Examples/JPA/EclipseLink-ORM.XML 是否
我有一个应用程序,它使用spring 4 . 0 . 1 JPA hiba Nate 4 . 2 . 8(spring的JpaTransactionManager,localcontainereentitymanagerfactorybean,带有HibernateJpaDialect和apache的BasicDataSource作为数据源)进行数据库访问。在某个时刻,应用程序开始一个长时间运行的
我正在构建一个应用程序,它应该服务于多个租户,并存储他们非常敏感的数据。每个租户都有多个用户。我的后端堆栈是用spring boot Hibernate5构建的。我希望hibernate处理多租户问题,所以我有两个问题要问专家: 如果我使用的是每租户模式范式,如何在登录时将用户名与租户关联?每个租户都有自己的用户表,那么我如何知道用户名属于哪个租户呢? 在注册时,什么是正确的方法来动态创建新模式?
问题内容: 是否可以强制休眠将歧视符列用于继承的继承类型?根据JPA2.0规范,这应该可行,但是我无法在休眠状态下实现。 例: 使用hibernate.hbm2ddl.auto create时,这甚至都不会在表PARENT中创建列TYPE。 我知道InheritanceType.JOINED可以在不定义鉴别符列的情况下工作,但是它是非常无效的,因为在使用鉴别符列中的信息时,休眠需要在父对象和所有子