Jooq too many clients - spring-boot

I'm facing an "Too many clients" error when using jooq in my spring boot application.
Currently I'm autowiring my DSLContext and was hoping that jooq auto closes the connections to my postgres, which apparently does not work properly.
Is there a way of releasing the connection manually?
#Autowired
lateinit var dsl: DSLContext
//further down
dsl.close() //didn't help
I found ideas which suggest to do something like this (Java code but you get the point ;) ),
but i would like to stick with the idea of autowiring the DSLContext (like above) and not the DataSource itself:
#Autowired
private DataSource dataSource;
//Further down
Connection con=dataSource.getConnection();
DSLContext create = DSL.using(con, SQLDialect.MYSQL);
//Execute code here
con.close();

There are probably control flows that lead to your con.close() call being skipped. However, you don't have to do the connection management manually with jOOQ. Just pass the DataSource to your DSL.using() call instead:
#Autowired
private DataSource dataSource;
//Further down
DSLContext create = DSL.using(dataSource, SQLDialect.MYSQL);

Related

Handling Datastax Java driver CqlSession in Spring Boot

Datastax Java driver documentation says to create a single instance of CqlSession for your Spring Boot application as building a session is a costly operation.
I want to manage the CqlSession in an effective way in Spring Boot such that CqlSession instance should be closed and not kept open in order to free underlying resources(TCP connections, thread pools…).
Driver documentation URL: https://docs.datastax.com/en/developer/java-driver/4.13/manual/core/
Here is my CqlSession Instance class. I use the Cqlsession instance to run Cql queries all over my Spring Boot application by injecting it as a Dependency in my #Service and #Repository classes.
Also I never close my Cql session manually but let the Spring handle it using #PreDestory annotation. Should session be closed as soon as a cql query is executed or should I allow spring to handle it as mentioned in the below code? I have realised that doing so, it takes a latency about 1-1.5 seconds for building cqlsession again and queries are ran super slow due to this.
#Configuration
public class CqlSessionInstance {
private CqlSession session;
#PostConstruct
private void initSession() {
getSession();
}
public final CqlSession getSession() {
if(session == null || session.isClosed()) {
session = CqlSession.builder().build();
}
return session;
}
#PreDestroy
public final void closeSession() {
if (session != null && !session.isClosed()) session.close();
}
}
Let me know if there are better ways to manage a CqlSession in Spring Boot
In my opinion, I suggest that you close the CqlSession yourself, since you know when you are executing as a specific request, and you know when to close it.
If you use the annotation #PreDestroy, you are depending on the Spring Life Cycle Management and as such it is hard to determine "when" exactly your component will be destroyed, and as such your session closed.

SpringBatch #Async method not working in persistent layer (JPAItemWriter)

SpringBoot Application with SpringBatch and JPA, without #Async all working fine but with #Async added in the REST API the job is completed but JPAItemWriter is not persisting the objects in the DB. looks like Transactional problem as am getting this exception.
Transaction Manager [org.sringframework.batch.support.transaction.ResourcelessTransactionManager] does not support transaction suspension.
I tried with different approaches like changing Propagation.Requires_New (Required, Supports) but nothing works, tried searching all the forums but no luck.
#Service
public class SampleWriter extends JpaItemWriter<TestEntity> {
#Autowired
EntityManager entityManager;
#Transactional(readOnly=false, propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
#Override
public void write(List<TestEntity> entities) {
this.doWrite(entityManager, entities);
}
}
It seems that you are configuring and using Spring Batch in a wrong way.
Firstly, it is using the default BatchConfigurer which the TransactionManager is ResourcelessTransactionManager that is mainly use for testing or acts as a "no-op" TransactionManager for the batch job that does not require any transaction which is definitely not your case now.
Secondly, Spring Batch will internally take care of managing the transaction boundary for processing each chunk , you do not need to extend JpaItemWriter and control the transaction behaviour using #Transactional by yourself.
So , read this section for how to configure Spring Batch , especially the part related to BatchConfigurer
On the other hand if you are using Spring-boot , it should already configure a JpaBatchConfigurer for you.

Spring Boot and Spring Session: How to control the DataSource

I'm experimenting with Spring Boot and Spring session together, specifically using JDBC.
Just adding the line in application.properties:
spring.session.store-type=jdbc
made it just work, which is nice because I happen to also have some data source properties in that file, ie
myapp.datasource.url=jdbc:mysql://localhost/etc...
myapp.datasource.driver-class-name=com.mysql.jdbc.Driver
But I'm actually using those for my own data source with my own configuration, like so:
#Configuration
#PropertySource("classpath:credentials.properties")
public class DataSourceConfig {
#Primary
#Bean(name = "dataSource")
#ConfigurationProperties(prefix = "myapp.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
}
and as far as I can tell, Spring Session is creating its own data source instead of using mine. Is there a way I can get it to use mine instead?
(my real data source has some additional configs with Hikari not shown here)
Spring Session itself does not create DataSource but rather uses the one present in your application context, if it's the either:
the only DataSource bean
DataSource marked as #Primary
Also if you wish to use a specific DataSource for Spring Session (for example, if you have multiple DataSources in your application) you can do that by:
annotating DataSource marked as designated for Spring Session by #SpringSessionDataSource (Spring Session 2.0 onwards)
providing JdbcTemplate bean that uses the desired DataSource and naming it springSessionJdbcOperations (Spring Session 1.x)
The Spring Session JDBC configuration capabilities and logic should be quite easy to understand from the JdbcHttpSessionConfiguration.

Reusing the JDBC connection from Hibernate with Spring

I've searched for a long time on this topic however I cannot find a solution to my specific issue. I am trying to figure out how I can pull the JDBC connection from Hibernate so that I can run a query for generating reports. I am trying to use a JDBC connection since my reports don't map well to the existing Entity situation that we have.
Right now, my application has a bean for a LocalContainerEntityManagerFactoryBean and a bean for DataSource, which is a just a DriverManagerDataSource, both residing in a core configuration file. The problem that I am having is, whenever I try to wire up my DAO to access the JDBC connection by doing something like this:
#PersistenceContext
private EntityManagerFactory entityManagerFactory;
private SessionFactory session;
public SystemUsageReportDAO() {
session = entityManagerFactory.unwrap(SessionFactory.class);
}
I simply get a null pointer exception at the constructor line. I've tried all manner of getting the connection from the EntityManagerFactory, however I'm not sure how I can do it. Any advice would be appreciated.
I know that my end goal is to get a Session object, and from there I can call doWork, however getting to that Session is proving quite the task for me.

How to get a DBUnit DatabaseConnection instance from Spring JdbcTemplate instance

I'm trying to use a Spring JdbcTemplate instance to generate a DataSet useable for subsequent DBUnit tests.
any ideas how to do that?
all the documentation I found where going from a JDBC Connection instance to a IDatabaseConnection instance.
But the code I have abstract all this away using Spring, and what I have is a JdbcTemplate instance.
Any ideas?
Your jdbcTemplate bean has a dataSource property, so you can either get it from the jdbcTemplate with its getter or inject the dataSource (which you already have defined somewhere in your applicationContext) in your class where you build the IDatabaseConnection and use it as a constructor-arg for that. (you should do the latter)
See the following blog for a detailed explanation and full example (written by a springsource trainer)
http://blog.zenika.com/index.php?post/2010/02/04/Testing-SQL-queries-with-Spring-and-DbUnit%2C-part-1
http://blog.zenika.com/index.php?post/2010/02/05/Testing-SQL-queries-with-Spring-and-DbUnit%2C-part-2

Resources