Из данного заголовка я получил рабочий образец без Spring Data Part, используя простой шаблон DataSource и JDBC с обновлением источника данных на , нажимая curl , чтобы также обновить компонент Datasource. Но не смог заставить его работать с Spring Data JPA, потратив бесчисленные часы поиска и просмотра различных сообщений в блоге, таких как spring-persistence-jpa-jndi-datasource , spring-boot-jndi-datasource
Я объясню все шаги и также свяжу git-проект с работающим примером JDBC-шаблона и JPA-проект ниже. Все компоненты настроены локально для демонстрации.
Добавление источника данных JNDI MySql в Wildfly (финальная версия 10.1.10)
Благодаря следующему видео - 3 способа добавления источника данных в Wildfly 9 ,
Я добавил два источника данных MySql, указывающих на две разные базы данных на моем локальном сервере mysql, развернув jar коннектора mysql и добавив источник данных с помощью консоли Wildfly, и оба теста с консоли прошли успешно.
Сервер конфигурации и клиент
Оба они настроены правильно и также протестированы. Клиенты конфигурации jdbcConfigClient и jpaConfigClient считывают свойство поиска JNDI с удаленного сервера конфигурации. MysqlConnector jar, ConfigClient и ConfigServer развернуты на локальном wildfly с помощью консоли Wildfly (только один клиент развернут для тестирования).
JdbcClient
Ниже приведен фрагмент конфигурации источника данных вместе с основным приложением и образцом контроллера для проверки обновления источника данных -
@SpringBootApplication
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
@RefreshScope
public class ConfigclientApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(ConfigclientApplication.class, args);
}
}
@RefreshScope
@RestController
class MessageRestController {
@Autowired
SampleDao dao;
@Value("${message:Hello default}")
private String message;
@RequestMapping("/message")
public String getMessage() {
return this.message;
}
@RequestMapping("/person")
public List<SampleEntity> getAll() {
return dao.findAll();
}
}
@RefreshScope
@Configuration
class DataSourceConfig {
@Value("${jndi.datasource.name}")
private String jndiName;
//@RequestMapping("/jndi")
public String getJndiName() {
return this.jndiName;
}
@Bean
@RefreshScope
public DataSource getDataSource() throws NamingException {
JndiDataSourceLookup jndiDataSourceLookup = new JndiDataSourceLookup();
System.out.println("Datasource jndi is "+getJndiName());
//return (DataSource) new JndiTemplate().lookup(getJndiName());
return jndiDataSourceLookup.getDataSource(getJndiName());
}
@Bean
@RefreshScope
public JdbcTemplate getJbdcTemplate() throws NamingException {
return new JdbcTemplate(getDataSource());
}
Для тестирования я нажал на запрос Get / person, чтобы получить список людей, и смог успешно получить ответ с обновлением источника данных, а также с помощью запроса curl для настройки клиента, как предложено в Getting Started Centralized Config . Для полной проверки проекта jdbcConfigClient
JPA Config Client
Вот когда все стало проблематично. Я пробовал много разных вещей, но даже с жестко закодированным параметром JNDI приложение не запустилось из-за разных причин, таких как отсутствие параметра URL, доступный компонент EntityManager или загрузка Hikari Config и сбой, даже если я не использую Hikari Источник данных в конфигурации Java Источник данных, который, как я полагаю, при загрузке Spring пытается загрузить по умолчанию. Я попытался исключить hikari cp из Spring data Starter, попытался исключить автоконфигурацию Datasource, используя свойство exlcude, равное @EnableAutoConfiguration
, в основном приложении до сих пор бесполезно. Я использую конфигурацию Jpa Datasource в обычных проектах без JNDI и сервера конфигурации.
Ниже приведен фрагмент конфигурации источника данных JPA с основным приложением:
SpringBootApplication
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
@EnableAutoConfiguration
@RefreshScope
public class ConfigclientApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(ConfigclientApplication.class, args);
}
}
@RefreshScope
@RestController
class MessageRestController {
@Autowired
SampleDao dao;
@Value("${message:Hello default}")
private String message;
@RequestMapping("/message")
public String getMessage() {
return this.message;
}
@RequestMapping("/person")
public List<SampleEntity> getAll() {
return dao.findAll();
}
}
@RefreshScope
@Configuration
@EnableJpaRepositories("com.example.demo.dao")
@EnableTransactionManagement
/*@EntityScan("com.example.demo.entity")
@ComponentScan("com.example.demo")*/
class DataSourceConfig {
@Value("${jndi.datasource.name}")
private String jndiName;
public String getJndiName() {
return this.jndiName;
}
@Bean
public DataSource getDataSource() throws NamingException {
//JndiDataSourceLookup jndiDataSourceLookup = new JndiDataSourceLookup();
//System.out.println("Datasource jndi is "+getJndiName());
//return (DataSource) new JndiTemplate().lookup(getJndiName());
//return jndiDataSourceLookup.getDataSource("java:/MySqlDS");
JndiObjectFactoryBean bean = new JndiObjectFactoryBean();
bean.setJndiName(getJndiName());
bean.setProxyInterface(DataSource.class);
bean.setLookupOnStartup(false);
bean.afterPropertiesSet();
return (DataSource)bean.getObject();
}
@Bean
public EntityManagerFactory entityManagerFactory() throws NamingException {
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setDataSource(getDataSource());
factory.setPackagesToScan("com.example.demo.entity");
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setDatabase(Database.MYSQL);
vendorAdapter.setShowSql(true);
factory.setJpaVendorAdapter(vendorAdapter);
factory.afterPropertiesSet();
//HashMap<String, Object> properties = new HashMap<>();
//properties.put("hibernate.generate-ddl", Boolean.TRUE.toString());
//properties.put("hibernate.hbm2ddl.auto", "update");
//properties.put("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
//entityManagerContainer.setJpaPropertyMap(properties);
return factory.getObject();
}
@Bean
public PlatformTransactionManager transactionManager() throws NamingException {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory());
return transactionManager;
}
}
Проект JPA можно найти здесь - JpaConfigClient
Если я удаляю всю конфигурацию источника данных и просто даю следующее свойство в файле удаленных свойств -
spring.datasource.jndi-name=java:/MySqlDs
Используя автоконфигурацию, конфигурация JPA завершается успешно, и я могу получить данные, используя запрос почтальона, но это не мое требование, и я не могу обновить источник данных, так как он автоматически конфигурируется при загрузке.
Также файл удаленных свойств с именем a-bootiful-client.properties содержит только следующие свойства:
#spring.datasource.jndi-name=java:/MySqlDs
jndi.datasource.name=java.name=java:comp/env/MySqlDs
message=Hi test
Когда приложение запускается, оно корректно ищет источник данных wildfly (я попытался назвать источник данных как java:comp/env/DatasourceName
, а также по умолчанию java:/DatasourceName
, но это не имело значения, и я получил те же проблемы, что и сообщалось выше. Не стесняйтесь раскошелиться на вышеуказанный проект.