org.springframework.orm.jpa.JpaSystemException: не удалось инициализировать прокси [Заказ#дата заказа] — нет сеанса;

#spring-boot #spring-data-jpa #spring-data

Вопрос:

В моем приложении spring boot версии 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

 @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; }  

I am trying to fetch Product from read only(slave) db in my service layer

 @Service @AllArgsConstructor public class ProductService{  private ProductRepository repo;   public void performOperation(){  Optionallt;Productgt; 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 JpaRepositorylt;Product, Longgt; {   lt;Tgt; Optionallt;Tgt; findById(final Long id, Classlt;Tgt; 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 возникает только тогда, когда я извлекаю продукт из подчиненной бд. Когда та же операция, которую я пытаюсь выполнить с помощью основной базы данных, я не получаю исключение LazyInitializationException.

Эту проблему на данный момент я решил, сделав заказ как тип выборки.жаждущий. Но я пытаюсь выяснить причину этого в случае с бд master slave и как добиться этого с помощью ЛЕНИВОГО типа выборки.

Ответ №1:

Прокомментируйте performOperation @Transactional как показано ниже:

 @Service @AllArgsConstructor public class ProductService{  private ProductRepository repo;   @Transactional  public void performOperation(){  Optionallt;Productgt; product = repo.findById(1l, Product.class);  if(product.isPresent()){  Order order = product.get().getOrder();  Date orderDate = order.getOrderDate(); // this line gives below exception  }  } }