Obtaining DataSource from Cayenne DataConext - java

Currently I am using Cayenne as my ORM. I need to get DataSource for initializing Velocity Engine in my code. I can manually create the datasource but I don't want to do it and want to use the existing datasource from Cayenne.

In Cayenne 3.1 it is rather trivial:
ServerRuntime runtime = .. // this exists in every app
DataSource ds = runtime.getDataSource("MyDataNode");
In the earlier versions it is only marginally harder:
DataDomain dd = context.getParentDataDomain();
DataSource ds = dd.getDataNode("MyDataNode").getDataSource();
The last approach works on 3.1 too BTW.

Related

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.

Setting the Transaction Isolation Level through Spring Boot properties

I have a spring boot application which I have configured most of the properties through the properties file. However, I was looking if there is a way to set the TRANSACTION_ISOLATION_LEVEL through the Spring boot properties. Could someone help me on this.
I'm initializing the data source bean in the following way:
#Bean
#ConfigurationProperties(prefix="spring.datasource")
public DataSource dataSource() {
return buildDataSource("spring.datasource");
}
private DataSource buildDataSource(String propPrefix) {
Stirng driverClassName = env.getProperty(propPrefix + ".driver-class-name");
return DataSourceBuilder.create()
.driverClassName(driverClassName)
.build();
}
Could someone please help me on how to specify the TRANSACTION_ISOLATION_LEVEL either through properties or during the data source initialization.
So, the javax.sql.DataSource does not provide a way to set default Transaction Isolation Level. Still, you can do it, but you must strict to particular implementation. Let me give you c couple of examples:
In case you use Apache BasicDataSource implementation of DataSource, then you can use this. This is for DBCP.
If you are using Apache BasicDataSource, but for DBCP2, you can do something like this.
But in most cases, if we are talking about Spring, we use Hikari Connection Pool. So, in case of HikariCP, you can use this method.
The same is applicable to Spring Boot. Let me explain - using Spring Boot properties file, you can set default transaction isolation level, but for specific DataSource, I mean this property:
spring.datasource.hikari.transaction-isolation
as you probably noticed, let you set default transaction isolation level for HikariCP (if you are using one) And this property:
spring.datasource.dbcp2.default-transaction-isolation
allow you to configure default isolation level for DBCP2.
Hope it helped, have a nice day! :)

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.

AutoCommit did not work with jOOQ 2.6.1 and Tomcat pooling

I use jOOQ 2.6.1 and the pooling from Tomcat (docs) and I have set autocommit to true.
PoolProperties p = new PoolProperties();
p.setDefaultAutoCommit(true);
p.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;" +
"org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");
p.setRemoveAbandoned(true);
p.setRemoveAbandonedTimeout(10);
then I created an Apache DataSource object:
org.apache.tomcat.jdbc.pool.DataSource dataSource = new DataSource
dataSource.setPoolProperties(p);
and I use the LazyConnectionDataSourceProxy from Spring:
LazyConnectionDataSourceProxy lazyConnection = new LazyConnectionDataSourceProxy(dataSource);
From jOOQ 2.6.1 is use the Factory:
public Factory createFactory() {
Settings settings = new Settings();
settings.getExecuteListeners().add(
"de.si.srv.data.SpringExceptionTranslationExecuteListener");
return new Factory(dataSource, SQLDialect.POSTGRES, settings);
}
if I do for example a select like this:
createFactory().select().from().fetch()
... jOOQ should close the connection automatically! But jOOQ does not close the connection.. All connections are after some time Abandoned.
Does anybody know a solution for my problem? I want that jOOQ closes the connections automatically! Or should I use an other pooling framework?
Which works better with jOOQ?
There have been quite a few changes and fixes around that area in jOOQ 3.x, the most important one being:
https://github.com/jOOQ/jOOQ/issues/2373
or should i use an other pooling framework ?
I don't think another pooling framework will help, here.
If you want to continue working with jOOQ 2.6.1 (instead of upgrading to jOOQ 3.2), I guess you might need to either:
Patch jOOQ and fix this issue
Handle the DataSource / Connection lifecycle yourself and pass a Connection to jOOQ

Jboss AP6 Transaction Manager Implementation

I'm just starting to learn Jboss AP6 and I have a few questions:
I created Local Tx Datasource (MySql Database)and can access it in my code using JNDI.
Now I would like to create kind of Transaction Management resource inside of my Jboss AP.
1) Is there any JTA feature built in Jboss AP6?
2) Can I apply it to my local DataSource which I created?
3) Can you please point me to any documentation which explains how to configure it and use it in my code, ot is there any article which coversthese topics in depth?
I googled it for some period of time, but haven't found any useful documentation. I don't want to use Spring/Hibernate out of the box solution just Mysql and plain JTA.
JBoss AP6 support JTA 1.1
Yes you can
If you declareLocalTxDatasource, this is mean, than whenever you get
connection from this datasource this connection will participate in "current" transaction.
If you want to manupulate transaction yourself, without EJB for example, you must enject TransactionManager from JNDI.
Example
TransactionManager tm = (TransactionManager)context.lookup("java:/TransactionManager");
tm.begin();
try{
DataSource ds = context.lookup("java:/testDS");
connection = ds.getConnection()
//do useful work
connection.close();
tm.commit();
}catch(Exception e){
tm.rollback()
}

Categories