Object initialization error SimpleDriverDataSource object with MongoDB - java

I need to set SimpleDriverDataSource object in order to create datasource with MongoDB, however I am not able to figure out what I should pass as "Driver".
I searched and found out that this is the JDBC driver for MongoDB "mongodb.jdbc.MongoDriver", but how do I set it up while initializing SimpleDriverDataSource object?
I have tried doing the below, but it shows error mentioned below
#Bean
protected DataSource dataSource() {
SimpleDriverDataSource ds = new SimpleDriverDataSource();
Driver driver = new Driver("mongodb.jdbc.MongoDriver");
ds.setDriverClass(driver);
ds.setUrl("jdbc:mongodb://localhost:27017:spring-security-sampledb");
ds.setUsername("root");
ds.setPassword("secret");
return ds;
}
error
Cannot instantiate the type Driver
I am new to Spring Boot. Can you please help me in implementing this?

java.sql.Driver is an interface, which means you cannot instantiate it like that. You may want to review the basics of Java before starting with Spring Boot.
In any case, you need to use new mongodb.jdbc.MongoDriver() instead of new Driver(), or use setDriverClass and pass it the class reference (mongodb.jdbc.MongoDriver.class) instead of a Driver instance.
Also, please be aware that SimpleDriverDataSource is probably the wrong choice, as - for example - it doesn't provide connection pooling.

Related

How to set the jdbc ClientInfo in a MySQL DataSource

In Java with MySQL we want to add the jdbc ClientInfo to identify the source of each query. Currently we can do something like:
try(Connection connection = dataSource.getConnection()){
connection.setClientInfo("ApplicationName", "MyApp");
}
But I need to add it to every connection created and means checking all the source code for places where a new connection is created. I will like to set it to the DataSource level.
So far what works for me is to extends the DataSource with a custom overriden getConnection method that calls setClientInfo. This is not only a dirty workarround but datasource specific.
I have seen that mysql driver has ClientInfoProviders like the default com.mysql.cj.jdbc.CommentClientInfoProvider. A custom ClientInfoProvider can be configured like:
Properties properties = new Properties();
properties.setProperty(PropertyKey.clientInfoProvider.getKeyName(), "foo.bar.CustomClientInfoProvider");
properties.setProperty(APPLICATION_NAME, "MyApp");
HikariConfig dataSourceConfig = new HikariConfig();
dataSourceConfig.setDataSourceProperties(properties);
...
But it is only called if someone calls the getClientInfo in the connection anyway.
So I will like to know:
Is there support in the MySql driver to set the clientInfo in the DataSource just by setting properties?
If there is a way. How can it be done?
I think you can use AspectJ as a possible solution for it. You can create an aspect which will intercept calls of the DataSource.getConnection method and then call the setClientInfo method with configured parameters when the connection is established.

Create SqlSession from existing Connection directly

I'm working with existing Java code wherein there is an existing JDBC connection pooling mechanism on deployed systems and an already existing setup to get JDBC connections. I'd like to leverage this to create a MyBatis SqlSession object without creating a Configuration, DataSource, and other things
I have code that already creates a java.sql.Connection object is given the desired resource. I'd like to leverage this and get that SqlSession object and use MyBatis from that point onwards.
I don't want MyBatis to manage connection pooling, determining which data source to use, etc. Is this possible?
I'm afraid you can't avoid creation of the Configuration object. It is used by the internal mybatis machinery like executors. But even if you could it will not help you much. In this case you will need to implement most of Configuration functionality yourself so it does not make sense to do that.
You main goal is to be able to use SqlSessionFactory.openSession(Connection connection) method. To do this you need to have SqlSessionFactory. The easiest way for you is to create Configuration like it is descried in mybatis documentation:
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment("development", transactionFactory, dataSource);
Configuration configuration = new Configuration(environment);
// set properties to configuration here
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(configuration);
Now if your connection pool does implement DataSource you use it directly to create environment. If it does not you need to create an adapter around your pool which implements javax.sql.DataSource.
My solution is similar to Roman's above, but I needed to create an Oracle datasource. For various reasons, the connection needs to be created using the Class.forName type sequence
Class.forName("oracle.jdbc.driver.OracleDriver");
String connectionString = "jdbc:oracle:thin:#//yadayada";
String username = "myusername";
String password = "mypassword";
OracleDataSource oracleDataSource = new OracleDataSource();
oracleDataSource.setURL(connectionString);
oracleDataSource.setPassword(password);
oracleDataSource.setUser(username);
environment = new Environment("dev",transactionFactory,oracleDataSource);
configuration = new Configuration(environment);
configuration.addMappers("MyMybatisMapper");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
return sqlSessionFactory.openSession();
What I was missing was the OracleDataSource object.

HikariDataSource close

I have implemented HikariCP which is working fine and I'm now planning to do a graceful shutdown of my application and I would like to make HikariCP close the database connection properly and not just killing the java application.
I was reading on google and I could see the HikariDataSource should have a close method.... but in fact I'm not able to see it available:
private static DataSoure ds;
:
public blabla() {
HikariConfig config = new HikariConfig();
config.setJdbc(jdbcURL);
:
ds = new HikariDataSource(config)
In Eclipse, if I tried ds.close()... Eclipse does not showing "close" as a valid method for HikariDataSource:
Am i doing something wrong? Probabily.... Any idea on how to make HikariCP to close properly the database connection?
Thanks,
Helio
You declare ds as javax.sql.DataSource and assign it with HikariDataSource. This way you will not have access to HikariDataSource native method.
((HikariDataSource)ds).close();
would do the trick.

Spring H2 embedded database [duplicate]

This question already has answers here:
Does Spring embedded database support different SQL dialects?
(3 answers)
Closed 5 years ago.
I want to create an in-memory database populated with test data for fast testing, so I declare this bean in my configuration file, but I also want so set this properties:
MODE=MySQL
DB_CLOSE_ON_EXIT=FALSE
but I don't know where to do it
#Bean
public DataSource dataSource(){
return
(new EmbeddedDatabaseBuilder())
.setType(EmbeddedDatabaseType.H2) //.H2
.addScript("classpath:db/H2.schema.sql")
.addScript("classpath:db/H2.data.sql")
.build();
}
try this
#Bean
public DataSource dataSource(){
return
new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.setName("testDB;DB_CLOSE_ON_EXIT=FALSE;MODE=MySQL")
.addScript("classpath:db/H2.schema.sql")
.addScript("classpath:db/H2.data.sql")
.build();
}
You can try using EmbeddedDatabaseBuilder.setName()
#Bean
public DataSource dataSource() {
return
new EmbeddedDatabaseBuilder()
.setName("testdb;MODE=MySQL;DB_CLOSE_ON_EXIT=false")
.setType(EmbeddedDatabaseType.H2) //.H2
.addScript("classpath:db/H2.schema.sql")
.addScript("classpath:db/H2.data.sql")
.build();
}
Note: I have not tried this myself, but found a clue on this answer
An alternative approach is to wire DataSources using properties. This way, you can set the JDBC URL which can contain additional properties.
The mode can be done via a SQL statement on H2, but I am pretty sure the DB_CLOSE_DELAY must be set as part of the URL which there is no easy hook into. You would be best just setting this in the application.properties/yml and let spring autoconfigure it
jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;MODE=MySQL would be the spring.datasource.url additional properties are available for the schema and data

How to get number of active connections using BasicDataSource object in java

I am trying to get the number of active connections using BasicDataSource object like following
BasicDataSource bds = new BasicDataSource();
bds.setDriverClassName("org.postgresql.Driver");
bds.setUrl(url);
bds.setUsername(username);
bds.setPassword(password);
and returning various values in json like
resourceObject.put("MaxTotal", bds.getMaxTotal());
resourceObject.put("NumActive", bds.getNumActive());
resourceObject.put("NumIdle", bds.getNumIdle());
I am always getting 0 for the number active and number idle, is there any other thing I forgot to set. Please help.
Are you sure, that your JdbcTemplate, or Spring Data repositories or whatever using exactly this datasouce in order to retrieve connections?) Becuase, for example, Spring Boot by default is using HikariDataSource (just to double check)
I cannot address BasicDataSource, but I can show how one can do it with HikariDataSource:
hikariDataSource.getHikariPoolMXBean().getActiveConnections();
hikariDataSource.getHikariPoolMXBean().getIdleConnections();
I know, that this does not answer the original question, but at least, maybe it will help someone.

Categories