有很多关于使用Master / Slave for Spring JPA的帖子,所以我选择使用AbstractRoutingDataSource
,这项工作在Jpa Repository
中有一个魅力。
已经实现了http://fedulov.website/2015/10/14/dynamic-datasource-routing-with-spring/,它在Spring JPA Repository中运行良好。
但是我需要使用Hibernate Criteria
,我无法使用多个数据源。
对于criteria Query
和Spring findBy
方法,我想要@Transactional。
但是当我使用Criteria时,它正在创建一个获取和释放JDBC连接。
如何在@Transactional
中同时执行这两项操作配置休眠:
@Bean(destroyMethod="")
@Primary
public EntityManagerFactory entityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setSharedCacheMode(SharedCacheMode.ENABLE_SELECTIVE);
em.setDataSource(primaryDataSource());
em.setPersistenceUnitName(Constants.MASTER_PERSISTENCE_CONTEXT);
em.setJpaDialect(new HibernateJpaDialect());
em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
em.setPackagesToScan(getPackagesToScan());
em.setJpaProperties(hibernateProperties());
em.afterPropertiesSet();
return em.getObject();
}
@Bean
@Primary
public JpaTransactionManager transactionManager() {
JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
jpaTransactionManager.setEntityManagerFactory(entityManagerFactory());
jpaTransactionManager.setGlobalRollbackOnParticipationFailure(false);
return jpaTransactionManager;
}
@Bean
//@Autowired
//@Primary
public RoutingDataSource primaryDataSource(){
RoutingDataSource routingDataSource=new RoutingDataSource();
Map<Object,Object> ds=new HashMap<>();
ds.put(DbType.MASTER,masterDataSource());
ds.put(DbType.REPLICA,slaveDataSource());
routingDataSource.setTargetDataSources(ds);
routingDataSource.setDefaultTargetDataSource(masterDataSource());
return routingDataSource;
}
@Bean
@Primary
public SessionFactory sessionFactory() throws IOException {
HibernateJpaSessionFactoryBean sessionFactory=new HibernateJpaSessionFactoryBean();
sessionFactory.setEntityManagerFactory(entityManagerFactory());
return sessionFactory;
}
public class RoutingDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DBContextHolder.getDbType();
}
}
使用以下内容创建标准: -
@Transactional(readOnly = true)
public abstract class BaseEntityDaoImpl<T extends BaseEntity<ID>, ID extends Serializable> {
@PersistenceContext(unitName = Constants.MASTER_PERSISTENCE_CONTEXT) EntityManager masEntityManager;
public Session getSession() {
return masEntityManager.unwrap(Session.class);
}
在这里,我总是得到Master会话为什么AbstractRoutingDataSource没有开始?
如何通过RoutingDS获得Slave Session?