spring-projects / spring-data-jpa

Simplifies the development of creating a JPA-based data access layer.
https://spring.io/projects/spring-data-jpa/
Apache License 2.0
2.92k stars 1.39k forks source link

Unable to start properly after packaging with graalvm #3515

Open king-from opened 1 week ago

king-from commented 1 week ago

When using multiple data source configurations in JPA, GraalVM was successfully packaged but could not run properly. However, it ran normally in the jar package ![Uploading 20240617155532.png…]()

christophstrobl commented 1 week ago

Please do no upload images but rather use proper GH markup. If you would like us to spend some time helping you to diagnose the problem, please spend some time describing it. Right now, we struggle to understand what you want to achieve. Ideally take the time to provide a complete minimal sample (something that we can unzip or git clone, build, and deploy) that reproduces the problem.

king-from commented 1 week ago

The operation is as follows: Configure multiple data sources through @ Configuration @ Enabling Transaction Management @ Enabling JpaRepositories. After packaging the grailvm, the jar package runs normally, but the executable file runs with an error as follows: [ROOT] appears to have started a thread named [HikariPool-1 housekeeper] but has failed to stop it. This is very similar to creating a memory leak Stack trace of thread: Org. galalvm. nativeimage. builder/com. oracle. svm. core. windows. headers. SynchAPI. WaitForSingleObject (SynchAPI. Java) Org. galalvm. nativeimage. builder/com. oracle. svm. core. windows. Windows Parker. park (Windows Platform Threads. java: 283) Org. galalvm. nativeimage. builder/com. oracle. svm. core. thread. PlatformThreads. parkCurrentPlatformOrCarrierThread (PlatformThreads. java: 937) POM configuration is: Spring boot 3.2.4

The data source configuration in the system is as follows: @Configuration public class PrimaryDataSourceConfig {

/**
 * 扫描spring.datasource.primary开头的配置信息
 *
 * @return 数据源配置信息
 */
@Primary
@Bean(name = "primaryDataSourceProperties")
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSourceProperties dataSourceProperties() {
    return new DataSourceProperties();
}

/**
 * 取主库数据源对象
 *
 * @param dataSourceProperties 注入名为primaryDataSourceProperties的bean
 * @return 数据源对象
 */
@Primary
@Bean(name = "primaryDataSource")
public DataSource dataSource(@Qualifier("primaryDataSourceProperties") DataSourceProperties dataSourceProperties) {
    return dataSourceProperties.initializeDataSourceBuilder().build();
}

/**
 * 该方法仅在需要使用JdbcTemplate对象时选用
 *
 * @param dataSource 注入名为primaryDataSource的bean
 * @return 数据源JdbcTemplate对象
 */
@Primary
@Bean(name = "primaryJdbcTemplate")
public JdbcTemplate jdbcTemplate(@Qualifier("primaryDataSource") DataSource dataSource) {
    return new JdbcTemplate(dataSource);
}

@Configuration

@EnableTransactionManagement @EnableJpaRepositories( basePackages = PrimaryJpaConfig.REPOSITORY_PACKAGE, entityManagerFactoryRef = "primaryEntityManagerFactory", transactionManagerRef = "primaryTransactionManager" ) public class PrimaryJpaConfig { static final String REPOSITORY_PACKAGE = "cn.swordsmen.agito.domain.repository"; private static final String ENTITY_PACKAGE = "cn.swordsmen.agito.domain.entity";

/**
 * 扫描spring.jpa.primary开头的配置信息
 *
 * @return jpa配置信息
 */
@Primary
@Bean(name = "primaryJpaProperties")
@ConfigurationProperties(prefix = "spring.jpa.primary")
public JpaProperties jpaProperties() {
    return new JpaProperties();
}

/**
 * 获取主库实体管理工厂对象
 *
 * @param primaryDataSource 注入名为primaryDataSource的数据源
 * @param jpaProperties     注入名为primaryJpaProperties的jpa配置信息
 * @param builder           注入EntityManagerFactoryBuilder
 * @return 实体管理工厂对象
 */
@Primary
@Bean(name = "primaryEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(
        @Qualifier("primaryDataSource") DataSource primaryDataSource,
        @Qualifier("primaryJpaProperties") JpaProperties jpaProperties,
        EntityManagerFactoryBuilder builder
) {
    return builder
            // 设置数据源
            .dataSource(primaryDataSource)
            // 设置jpa配置
            .properties(jpaProperties.getProperties())
            // 设置实体包名
            .packages(ENTITY_PACKAGE)
            // 设置持久化单元名,用于@PersistenceContext注解获取EntityManager时指定数据源
            .persistenceUnit("primaryPersistenceUnit").build();
}

/**
 * 获取实体管理对象
 *
 * @param factory 注入名为primaryEntityManagerFactory的bean
 * @return 实体管理对象
 */
@Primary
@Bean(name = "primaryEntityManager")
public EntityManager entityManager(@Qualifier("primaryEntityManagerFactory") EntityManagerFactory factory) {
    return factory.createEntityManager();
}

/**
 * 获取主库事务管理对象
 *
 * @param factory 注入名为primaryEntityManagerFactory的bean
 * @return 事务管理对象
 */
@Primary
@Bean(name = "primaryTransactionManager")
public PlatformTransactionManager transactionManager(@Qualifier("primaryEntityManagerFactory") EntityManagerFactory factory) {
    return new JpaTransactionManager(factory);
}

}