How to work with a HikariCP connection pool? - activejdbc

How do I get activejdbc working with a HikariCP connection pool? Mostly want this for documentation purposes.
I've tried a few different methods but none have worked so far.

Figured it out for postrgresql:
public static final HikariConfig hikariConfig() {
HikariConfig hc = new HikariConfig();
hc.setDataSourceClassName("org.postgresql.ds.PGSimpleDataSource");
hc.setJdbcUrl(DataSources.PROPERTIES.getProperty("jdbc.url"));
hc.setUsername(DataSources.PROPERTIES.getProperty("jdbc.username"));
hc.setPassword(DataSources.PROPERTIES.getProperty("jdbc.password"));
hc.setMaximumPoolSize(10);
return hc;
}
public static final HikariDataSource hikariDataSource = new HikariDataSource(hikariConfig());
public static final void dbInit() {
Base.open(hikariDataSource); // get connection from pool
}
public static final void dbClose() {
Base.close();
}

Related

Cannot read properties when used MockWebServer

Hi I am new to the Junit Testing and am trying to test the third party call, for that I have used MockWebServer from okhttp3, the mockWebServer does the job of giving me a proper mocked response but in the class that I am trying to test has the following
#Autowired
Environment env
....
...
..
String url = env.getProperty(shop.url);
The above is significant as it gets the url from application.yml
But the env is null whenever I am running that particular test method which uses MockWebServer
Main Class
Class ConnectionService {
#Autowired
Environment environment;
public ConnectionService(WebClient.Builder builder) {
this.webClient = builder.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.baseUrl(usersBaseUrl).build();
}
public void getShops(){
...
..
String url = env.getProperty(shop.url);
..
..
}
Test Class
#ExtendWith(SpringExtension.class)
#SpringBootTest
#AutoConfigureWireMock(port = 0)
class ConnectionServiceTest {
public static MockWebServer mockWebServer;
private static ConnectionService connectionService;
#BeforeAll
public static void setUp() throws IOException {
mockWebServer = new MockWebServer();
connectionService = new ConnectionService(WebClient.builder(),
mockWebServer.url("/").toString();
}
#AfterAll
static void tearDown() throws IOException {
mockWebServer.shutdown();
}
#Test
void testMethod() {
MockResponse mockResponse = new MockResponse()
.addHeader("Content-Type", "application/json; charset=utf-8")
.setBody("{\"status\":\"up\",\"details\":\"details\"}")
.throttleBody(16, 5, TimeUnit.SECONDS);
mockWebServer.enqueue(mockResponse);
connectionService.getShops();
}
}
Could someone please help me out figure what am I doing wrong, is it the MockWebServer that is causing environment to be null ? even the other properties in other files are null. Thanks in advance :)
I tried to test the WebClient by making use of MockWebServer, although it worked but now I cannot read any properties either from application.yml or otherProperties.properties as the environments variables are not getting injected

java.lang.NullPointerException: null on AutoWiring a bean in StandAlone App

When trying to use #AutoWire feature with one of StandAlone Application unable to do so instead getting Null Pointer Exception. Please highlight my mistakes if any. Your help is appreciated.
Spring Ver 5.1.5.RELEASE and we're not using any xml config file to tell spring there are annotated classes to look into instead using #ComponentScan or #EnableAutoConfiguration at the top of AppConfig and boost strap the Context from main() class as a first line. But Autowiring works perfectly with internal bean/java classes of jdk(Environment) but not with custom POJO classes. If we're trying to get through getBean method then it works. But I'm trying to avoid creating context everywhere and using getBean() Please Refer below and help me only with your valuable guidelines.
public class ContextMaster {
private static AnnotationConfigApplicationContext appContext;
public static AnnotationConfigApplicationContext getApplicationContext() {
if (appContext == null) {
appContext = new AnnotationConfigApplicationContext(ContextConfig.class);
//appContext = new AnnotationConfigApplicationContext("com.xx.xx.xxx","xx.xxx.xxxx.xxx.datamanager");
logger.debug("Context Invoked !!");
}
return appContext;
}
}
#Configuration
#EnableAutoConfiguration
#PropertySource("classpath:db.properties")
#EnableTransactionManagement
#ComponentScans(value = {
#ComponentScan(basePackages = "xxxxx.datamanager"),
#ComponentScan(basePackages = "com.xx.xx.xxx"),
#ComponentScan(basePackages = "com.xx.xx.xxx.utils")})
public class AppConfig {
#Autowired
private Environment env;
#Bean
public DataSource getDataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(env.getProperty("db.driver"));
dataSource.setUrl(env.getProperty("db.url"));
return dataSource;
}
#Bean
public LocalSessionFactoryBean getSessionFactory() {
LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
//LocalSessionFactoryBean sessionFactoryBean = new AnnotationSessionFactoryBean();
factoryBean.setDataSource(getDataSource());
Properties props=new Properties();
props.put("hibernate.show_sql", env.getProperty("hibernate.show_sql"));
props.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
props.put("hibernate.cache.region.factory_class", env.getProperty("hibernate.cache.region.factory_class"));
factoryBean.setHibernateProperties(props);
factoryBean.setAnnotatedClasses(xx.class, xxxx.class, xxxx.class, xxx.class);
return factoryBean;
}
#Bean
public HibernateTransactionManager getTransactionManager() {
return transactionManager;
}
}
// Here is NPE thrown when tried with auto-configured bean
#Component
public class Good extends Good11 {
#Autowired
private RxxxDyyyyHelper rdh;
//RxxxDyyyyHelper rdh =
ContextHelper.getApplicationContext().getBean(RxxxDyyyyHelper .class);
rdh.setProperty(); // NPE here
rdh.getProperty(); // NPE
}
// Here we're trying to initiate the LosUtils class
public class LosUtils {
public static void main(String args[]) throws Exception {
AnnotationConfigApplicationContext applicationContext = `ContextHelper.getApplicationContext();`
}
It seems like you didn't put the full code here, because your Good class won't compile this way..

Using #Value in PersistanceConfig

I am trying to database config dynamicly in dependence to environment.
I would like to use #Value to get database info.
My Config file is:
#Configuration
#EnableTransactionManagement
#ComponentScan(basePackages = "service")
#PropertySource("classpath:application-${environment}.properties")
#EnableJpaRepositories("repositories")
public class PersistanceConfig {
private final String MODEL_PATH = "model";
#Value("${mariadb.driver}:#{null}")
private String driver;
#Value("${mariadb.url}:#{null}")
private String url;
#Value("${mariadb.username}:#{null}")
private String username;
#Value("${mariadb.password}:#{null}")
private String password;
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean em
= new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan(new String[] {MODEL_PATH});
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(additionalProperties());
return em;
}
#Bean
public DataSource dataSource(){
Assert.notNull(driver, "JBDC driver is not defined");
Assert.notNull(url, "url is not defined");
Assert.notNull(username, "username is not defined");
Assert.notNull(password, "password is not defined");
final BasicDataSource source = new BasicDataSource();
source.setDriverClassName(driver);
source.setUrl(url);
source.setUsername(username);
source.setPassword(password);
return source;
}
#Bean
public PlatformTransactionManager transactionManager(
EntityManagerFactory emf){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
#Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
return new PersistenceExceptionTranslationPostProcessor();
}
Properties additionalProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
properties.setProperty(
"hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
return properties;
}
#Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer(){
return new PropertySourcesPlaceholderConfigurer();
}
}
During compile time is property-file properly found and variables driver, url, username and password are properly filled.
Unfortunatelly, during runtime #Value doesn't execute and fill the expression into variable (subsequent exceptions is: "Could not use '${mariadb.driver}' to connect").
According another answer here I added static PropertySourcesPlaceholderConfigurer bean, but i had no effect.
I also tried different combination of Environmnet class and PropertySource values but nothing worked.
Thank you for your advise.
Problem was pretty stupid.
I had my configurations file in root of project, not root of src java folder.

Reading application.properties from any class in spring boot

When I add a property in the application.properties files, this can be access from the main class without any problem.
#SpringBootApplication
#ComponentScan(basePackages = "com.example.*")
public class MailTestApplication implements CommandLineRunner {
#Value("${admin.mail}")
String email;
public static void main(String[] args) {
SpringApplication.run(MailTestApplication.class, args);
}
#Override
public void run(String... strings) throws Exception {
System.out.println(email);
Email email = new Email();
email.sendMail();
}
}
However, when I try to access it from any other class it is never retrieved.
#Component
public class Email {
#Autowired
private MailSender sender;
#Value("${admin.mail}")
String email;
public Email() {
}
public void sendMail() {
SimpleMailMessage msg = new SimpleMailMessage();
System.out.println(email);
msg.setTo("sample#email.com");
msg.setSubject("Send mail by Spring Boot");
msg.setText("Send mail by Spring Boot");
sender.send(msg);
}
}
I was reading some of the previous questions other users posted without a clear result for me. I even tried to find some examples with similar resutl.
Could someone give me any clue about this?
Thanks a lot in advance.
The #Value should work (Im asuming your class is under the com.example.* package since you are scanning that package) but if you want to do it another way this is what im using :
public class JpaConfiguration {
public static final String TRANSACTION_MANAGER_NAME = "jpaTransactionManager";
#Autowired
Environment applicationProperties;
Then to use it
#Bean
public DriverManagerDataSource driverManagerDataSource() {
DriverManagerDataSource driverConfig = new DriverManagerDataSource();
driverConfig.setDriverClassName(applicationProperties.getProperty("data.jpa.driverClass"));
driverConfig.setUrl(applicationProperties
.getProperty("data.jpa.connection.url"));
driverConfig.setUsername(applicationProperties
.getProperty("data.jpa.username"));
driverConfig.setPassword(applicationProperties
.getProperty("data.jpa.password"));
return driverConfig;
}
UPDATE AFTER GETTING THE GITHUB REPO
I Don't really know what you are trying to build but :
If you do this:
#Override
public void run(String... strings) throws Exception {
//System.out.println(email);
Email email = new Email();
email.sendMail();
}
Then you are creating the instance of the class, and not spring. so you shouldn't be creating the instance yourself there it should be spring.
That said, i dont know if you are creating a web application a command line application or both.
That said ill give you a minor solution to show you that the dependency injection is in fact working.
1_ add a getter to your email on email class. remove the CommandLine interface (If you want to implement this i would recomend you to put CommandLine implmentations on another package say Controller);
And then run your app like this:
#SpringBootApplication
#ComponentScan(basePackages = "com.example")
public class MailTestApplication {
#Value("${admin.mail}")
String email;
public static void main(String[] args) {
// SpringApplication.run(MailTestApplication.class, args);
final ConfigurableApplicationContext context = new SpringApplicationBuilder(MailTestApplication.class).run(args);
Email e = context.getBean(Email.class);
System.out.println(e.getEmail());
}
The Key thing I want to show is that the instance is created by spring thats why the wiring works. and the email gets printed in the console.
Regarding the email class :
#Component
public class Email {
// #Autowired
// private MailSender sender;
#Value("${admin.mail}")
String email;
public Email() {
}
public void sendMail() {
SimpleMailMessage msg = new SimpleMailMessage();
System.out.println(email);
msg.setTo("sample#email.com");
msg.setSubject("Send mail by Spring Boot");
msg.setText("Send mail by Spring Boot");
// sender.send(msg);
}
public String getEmail() {
return email;
}
}
I Comment out the MailSender since I think you need to configure that too, i have made a custom mailSender that uses gmail and other for mailChimp that i can share with you if you need. but again I dont really know what your intent with the app is.
Hope the info helps you.

RavenDB- Building Session Factory, singleton DocumentStore

I'm a newbie to RavenDb. I've built the RavenDB session factory like the below code. The idea is very much driven from the way we build NHibernateSessionHelpers. I hope this should work really well in production. Are there any suggestions to improve this from people who are experts in RavenDB?
public class MXRavenDbSessionHelper
{
//---All new lazy singleton that's thread safe.---
private static Lazy<IDocumentStore> _lazyDocStore = new Lazy<IDocumentStore>(() => InitializeSessionFactory());
private MXRavenDbSessionHelper() { }
private static IDocumentStore SessionFactory
{
get
{
return _lazyDocStore.Value;
}
}
public static IDocumentSession OpenSession()
{
return SessionFactory.OpenSession();
}
private static IDocumentStore InitializeSessionFactory()
{
var _docStore = new DocumentStore { ConnectionStringName = "RavenDBConnString", DefaultDatabase = "MXMunky" }; //One more way is this : _store = new DocumentStore { Url = "http://localhost:7000" };
_docStore.Initialize();
_docStore.Conventions.IdentityPartsSeparator = "-";
IndexCreation.CreateIndexes(typeof(Location).Assembly, _docStore);
return _docStore;
}
}
I don't think you need to keep _docStore separately. See Jon Skeet's singleton patterns (#6).
Other than that, I don't see anything particularly wrong with it.
I'd be careful not to use this when unit testing. There, you actually do want a new docstore instance for each test - and they should be disposed properly.