我的spring启动v2.5.5应用程序配置了主从mysql数据库。
主数据源配置
@EnableJpaRepositories(
basePackages = "com.dummy",
excludeFilters = @ComponentScan.Filter(ReadOnlyRepository.class),
entityManagerFactoryRef = "primaryEntityManagerFactory",
transactionManagerRef = "primaryTransactionManager"
)
@Configuration
public class PrimaryDataSourceConfig {
@Autowired
private Environment env;
@Value("${master.jdbc.url}")
private String jdbcURL;
@Bean
@Primary
public DataSource primaryDataSource() throws Exception {
return DataSourceBuilder.create()
.driverClassName("com.mysql.jdbc.Driver")
.url(jdbcURL)
.username("root")
.password("root").build();
}
@Bean
@Primary
public LocalContainerEntityManagerFactoryBean primaryEntityManagerFactory() throws Exception {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(primaryDataSource());
em.setPackagesToScan("com.dummy");
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(false);
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());
return em;
}
@Bean
@Primary
public PlatformTransactionManager primaryTransactionManager() throws Exception {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(primaryEntityManagerFactory().getObject());
return transactionManager;
}
final Properties additionalProperties() {
final Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("primary.hibernate.hbm2ddl.auto"));
hibernateProperties.setProperty("hibernate.dialect", env.getProperty("primary.hibernate.dialect"));
hibernateProperties.setProperty("hibernate.show_sql", env.getProperty( "primary.hibernate.show_sql"));
hibernateProperties.setProperty("hibernate.cache.use_second_level_cache", "false");
return hibernateProperties;
}
}
从数据源配置
@Configuration
@EnableJpaRepositories(
basePackages = "com.dummy.submodule",
includeFilters = @ComponentScan.Filter(ReadOnlyRepository.class),
entityManagerFactoryRef = "readOnlyEntityManagerFactory",
transactionManagerRef = "readOnlyTransactionManager"
)
public class ReadOnlyDataSourceConfig {
@Autowired
private Environment env;
@Value("${slave.jdbc.url}")
private String jdbcURL;
@Bean
public DataSource readOnlyDataSource() throws Exception {
return DataSourceBuilder.create()
.driverClassName("com.mysql.jdbc.Driver")
.url(jdbcURL)
.username("root")
.password("root").build();
}
@Bean
public LocalContainerEntityManagerFactoryBean readOnlyEntityManagerFactory() throws Exception {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(readOnlyDataSource());
em.setPackagesToScan("com.dummy.submodule");
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(false);
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());
return em;
}
@Bean
public PlatformTransactionManager readOnlyTransactionManager() throws Exception {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(readOnlyEntityManagerFactory().getObject());
return transactionManager;
}
final Properties additionalProperties() {
final Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("readonly.hibernate.hbm2ddl.auto"));
hibernateProperties.setProperty("hibernate.dialect", env.getProperty("readonly.hibernate.dialect"));
hibernateProperties.setProperty("hibernate.show_sql", env.getProperty( "readonly.hibernate.show_sql"));
hibernateProperties.setProperty("hibernate.cache.use_second_level_cache", "false");
return hibernateProperties;
}
}
实体@Entity
@Getter
@Setter
public class Product implements Serializable {
private static final long serialVersionUID = 8135071385764991866L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@OneToOne(fetch = FetchType.LAZY)
@NotNull
@JoinColumn(name = "status")
private Order order
}
@Getter
@Setter
@Entity
public class Order implements Serializable {
private static final long serialVersionUID = 8135071385764991879L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private Date orderdate;
}
我正在尝试从我的服务层只读(从)数据库中获取产品
@Service
@AllArgsConstructor
public class ProductService{
private ProductRepository repo;
public void performOperation(){
Optional<Product> product = repo.findById(1l, Product.class);
if(product.isPresent()){
Order order = product.get().getOrder();
Date orderDate = order.getOrderDate(); // this line gives below exception
}
}
}
只读的存储库:
@Repository
@ReadOnlyRepository
public interface ProductRepository extends JpaRepository<Product, Long> {
<T> Optional<T> findById(final Long id, Class<T> type);
}
异常:2021-10-22 12:35:11,109 ERROR [http-nio-8080-exec-8] com.dummy.logging.LoggingClass:41 Exception_Occurred::{}
org.springframework.orm.jpa.JpaSystemException: could not initialize proxy [com.dummy.submodule.entities.Order#orderdate] - no Session; nested exception is org.hibernate.LazyInitializationException: could not initialize proxy [com.dummy.submodule.entities.Order#orderdate] - no Session
注意:LazyInitializationException仅在我从从属数据库获取Product时发生。当我试图使用主数据库执行相同的操作时,我没有得到LazyInitializationException。
这个问题现在我已经处理了订单作为FetchType.EAGER。但我试图找出背后的原因,在主从db的情况下,以及如何实现它与LAZY取回类型。
用@Transactional
注释performOperation
,如下所示:
@Service
@AllArgsConstructor
public class ProductService{
private ProductRepository repo;
@Transactional
public void performOperation(){
Optional<Product> product = repo.findById(1l, Product.class);
if(product.isPresent()){
Order order = product.get().getOrder();
Date orderDate = order.getOrderDate(); // this line gives below exception
}
}
}