connection leakage with hikari CP - hikaricp

I have jdbs template for sql for sql statements, and use hikari connection pool, after after several calls
i took exception, i used try-with-resources, where is my mistake?(Servlet Container -Tomcat)
public class SimpleJdbcTemplate {
private Connection connection;
private DataSource dataSource;
private ResultSet resultSet;
PreparedStatement preparedStatement;
public SimpleJdbcTemplate(Connection connection) {
this.connection = connection;
}
//private DataSourse datasource - из hikariconnectionpool
public SimpleJdbcTemplate(DataSource dataSource) {
this.dataSource = dataSource;
}
public <T> List<T> query(String sql, RowMapper<T> rowMapper, Object... args) {
try (PreparedStatement preparedStatement = dataSource.getConnection().prepareStatement(sql)){
resultSet = null;
List<T> result = new ArrayList<>();
int position = 1;
for (Object arg : args) {
preparedStatement.setObject(position, arg);
position++;
}
if (sql.contains("UPDATE") || sql.contains("update") ||sql.toLowerCase().contains("delete")||sql.toLowerCase().contains("insert")) {
preparedStatement.executeUpdate();
} else{
resultSet = preparedStatement.executeQuery();
if (resultSet == null) {
throw new SQLException("No resultsSet");
}
while (resultSet.next()) {
result.add(rowMapper.mapRow(resultSet));
}
}
log.info(result.toString());
return result;
} catch (SQLException e) {
throw new IllegalStateException(e);
Logs:
24-Oct-2020 13:46:16.633 SEVERE [http-nio-8080-exec-3] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [servlets.view.MessendjerViewServlet] in context with path [/LabWork_war] threw exception
java.lang.IllegalStateException: java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30014ms.
at repository.utill.SimpleJdbcTemplate.query(SimpleJdbcTemplate.java:52)
at repository.jdbc.UserRepositoryImpl.findUserByUUID(UserRepositoryImpl.java:84)
at service.UserService.findUser(UserService.java:71)
at servlets.filter.AuthFilter.doFilter(AuthFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1589)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30014ms.
at com.zaxxer.hikari.pool.HikariPool.createTimeoutException(HikariPool.java:695)
at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:197)
at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:162)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:100)
at repository.utill.SimpleJdbcTemplate.query(SimpleJdbcTemplate.java:27)
... 22 more

Okey i founded mistake this line is dont work correctly(try-with-resources)
(reparedStatement preparedStatement = dataSource.getConnection().prepareStatement(sql))
i think when i try to close connection it tooks a random connection from datasource(dataSource.getConnection()),so,my connection was always open, i reformated code to this
public class SimpleJdbcTemplate {
DataSource dataSource;
//private DataSourse datasource - из hikariconnectionpool
public SimpleJdbcTemplate(DataSource dataSource) {
this.dataSource = dataSource;
}
public <T> List<T> query(String sql, RowMapper<T> rowMapper, Object... args) { //TODO repair connection leak
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
connection = dataSource.getConnection();
preparedStatement = connection.prepareStatement(sql);
resultSet = null;
List<T> result = new ArrayList<>();
int position = 1;
for (Object arg : args) {
preparedStatement.setObject(position, arg);
position++;
}
if (sql.contains("UPDATE") || sql.contains("update") || sql.toLowerCase().contains("delete") || sql.toLowerCase().contains("insert")) {
preparedStatement.executeUpdate();
} else {
resultSet = preparedStatement.executeQuery();
if (resultSet == null) {
throw new SQLException("No resultsSet");
}
while (resultSet.next()) {
result.add(rowMapper.mapRow(resultSet));
}
}
log.info(result.toString());
return result;
} catch (SQLException e) {
throw new IllegalStateException(e);
} finally {
try {
if (resultSet != null) {
resultSet.close();
log.info("resultes finaly closed? - {}", resultSet.isClosed());
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
if (preparedStatement != null) {
try {
preparedStatement.close();
preparedStatement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
try {
if (connection != null) {
connection.close();
connection.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
all worked as it should

Related

Master -Slave Database Configuration With Hikari Pool

I have two DataSource Beans one with #Primary annotation.
Individual Hikari pools are created for every DataSource.
I am trying to change the HikariDataSource from Pool 1(if connection is not available) to Pool 2 .
#Primary
#Bean(destroyMethod = "close", name = "dataSource")
public CustomHikariDataSource dataSource() throws SQLException {
try {
primaryDataSource = mainDataSource();
} catch (Exception e) {
primaryDataSource = secondaryDataSource();
}
HikariConfig config = new HikariConfig();
config.setDataSource(primaryDataSource);
config.setPoolName("POOL_PRIMARY");
config.setAllowPoolSuspension(true);
config.setIdleTimeout(10000);
config.setMaxLifetime(30000);
return new CustomHikariDataSource(config);
}
#Bean(destroyMethod = "close", name = "failoverDataSource")
public CustomHikariDataSource failoverDataSource() throws SQLException {
secondaryDataSource = secondaryDataSource();
HikariConfig config = new HikariConfig();
config.setDataSource(secondaryDataSource);
config.setPoolName("POOL_SECONDARY");
config.setAllowPoolSuspension(true);
return new CustomHikariDataSource(config);
}
private DataSource mainDataSource() {
return dataSourceProperties().initializeDataSourceBuilder().build();
}
private DataSource secondaryDataSource() {
return failoverDataSourceProperties().initializeDataSourceBuilder().build();
}
Where is the actual Problem?
Finally i am able to achieve it by Overriding getConnection() method from HikariDataSource.class
#Override
public Connection getConnection() throws SQLException {
if (isClosed()) {
throw new SQLException("HikariDataSource " + this + " has been closed.");
}
if (fastPathPool != null && (fastPathPool.poolState == 0 || fastPathPool.poolState == 1)) {
try {
fastPathPool.resumePool();
con = fastPathPool.getConnection();
} catch (Exception e) {
}
if (con.isClosed()) {
config = pool.config;
fastPathPool.suspendPool();
} else
return con;
}
config.setDataSource(dataSource);
config.setAllowPoolSuspension(true);
config.setMinimumIdle(minIdle);
pool = new HikariPool(config);
HikariPool result = pool;
if (result == null) {
synchronized (this) {
result = pool;
if (result == null) {
validate();
System.out.println("{} - Starting..." + getPoolName());
try {
pool = result = new HikariPool(this);
this.seal();
} catch (PoolInitializationException pie) {
if (pie.getCause() instanceof SQLException) {
throw (SQLException) pie.getCause();
} else {
throw pie;
}
}
System.out.println("{} - Start completed." + getPoolName());
}
}
}
return result.getConnection();
}
For complete class ,feel free to ping me.
Happy Coding ! :)

How to get the number of Active Connections for HikariCP

I was trying to log the number of current active connections. I am using com.zaxxer.hikari.HikariJNDIFactory as my data source factory.
final Context context = new InitialContext();
HikariConfig hikariConfig = new HikariConfig();
hikariConfig.setDataSource((DataSource) ((Context)context.lookup("java:comp/env")).lookup("jdbc/mydb"));
HikariPool hikariPool = new HikariPool(hikariConfig);
LOGGER.log(Level.INFO, "The count is ::" + hikariPool.getActiveConnections());
But it is throwing the following exception:
java.lang.RuntimeException: java.lang.NullPointerException
at com.zaxxer.hikari.util.PoolUtilities.createInstance(PoolUtilities.java:105)
at com.zaxxer.hikari.metrics.MetricsFactory.createMetricsTracker(MetricsFactory.java:34)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:131)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:99)
at com.something.servlet.HikariConnectionCount.doGet(HikariConnectionCount.java:35)
Where HikariConnectionCount.java is the file I have written
Programatic access is documented here https://github.com/brettwooldridge/HikariCP/wiki/MBean-(JMX)-Monitoring-and-Management
Here's a dirty recipe:
import org.springframework.beans.DirectFieldAccessor;
import com.zaxxer.hikari.HikariDataSource;
import com.zaxxer.hikari.pool.HikariPool;
public class HikariDataSourcePoolDetail {
private final HikariDataSource dataSource;
public HikariDataSourcePoolDetail(HikariDataSource dataSource) {
this.dataSource = dataSource;
}
public HikariPool getHikariPool() {
return (HikariPool) new DirectFieldAccessor(dataSource).getPropertyValue("pool");
}
public int getActive() {
try {
return getHikariPool().getActiveConnections();
} catch (Exception ex) {
return -1;
}
}
public int getMax() {
return dataSource.getMaximumPoolSize();
}
}
Use it thus:
try {
HikariDataSourcePoolDetail dsd = new HikariDataSourcePoolDetail((HikariDataSource)dataSource);
log.info("HikariDataSource details: max={} active={}", dsd.getMax(), dsd.getActive());
} catch (Exception e) {
log.error("HikariDataSourcePoolDetail failed: ", e);
}

Javafx Task for Bluetooth data reciever

I am creating javafx application where I have this case that I need to listen for data sent over Bluetooth.
I have one fxml window on which I need to initialize Bluetooth and start listening from data.
Following is my Code for fxml controller:
//all imports
public class NewBarcodeInvoicePaneController implements Initializable{
private BluetoothController bc;
public BluetoothController getBc() {
return bc;
}
#Override
public void initialize(URL location, ResourceBundle resources) {
try {
bc = new BluetoothController();
new Thread(bc).start();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
And BluetoothController is task where I initialize bluettoth and listen to the data
public class BluetoothController extends Task<Void> {
#Override
protected Void call() throws Exception {
LocalDevice local = null;
StreamConnectionNotifier notifier;
StreamConnection connection = null;
// setup the server to listen for connection
try {
local = LocalDevice.getLocalDevice();
try {
local.setDiscoverable(DiscoveryAgent.GIAC);
} catch (BluetoothStateException e) {
}
UUID uuid = new UUID(80087355); // "04c6093b-0000-1000-8000-00805f9b34fb"
String url = "btspp://localhost:" + uuid.toString() + ";name=RemoteBluetooth";
notifier = (StreamConnectionNotifier) Connector.open(url);
} catch (Exception e) {
e.printStackTrace();
return null;
}
try {
System.err.println("THIS IS HAPENING");
connection = notifier.acceptAndOpen();
System.err.println("HAPENING???????????????????????????");
InputStream inputStream = connection.openInputStream();
BufferedReader bReader = new BufferedReader(new InputStreamReader(inputStream));
String lineRead = bReader.readLine();
connection.close();
inputStream.close();
notifier.close();
local.setDiscoverable(DiscoveryAgent.NOT_DISCOVERABLE);
JSONParser parser = new JSONParser();
Object obj = parser.parse(lineRead);
JSONArray array = (JSONArray) obj;
array.stream().map((o) -> (String) o).forEach((stringObj) -> {
System.out.println(stringObj);
});
System.out.println("AFTER DATA RECIEVED");
} catch (Exception e) {
e.printStackTrace();
return null;
}
return null;
}
}
It Works fine if I send data over bluetooth and blocking call to notifier.acceptAndOpen() is unblocked.
My problem is when we do not pass any data and I just want to close the window I opened..
It still have blocking call open with extra thread by the task.
I tried to cancel BluetoothController task in Main controller where I open this window like following
private void openNewBarcodeInvoicePane(ActionEvent ae) {
//following are custom classes to open windows from fxml and getting controller back for further manipulation
PostoryModalWindow modalWindow = new PostoryModalWindow();
modalWindow.openNewModalPaneWithParent("New Invoice", "fxml/newbarcodeinvoicepane.fxml", ae);
//getting controller object
NewBarcodeInvoicePaneController controller = (NewBarcodeInvoicePaneController) modalWindow.getDswFromController();
controller.getWindowStage().showAndWait();
BluetoothController bc = controller.getBc();
if(bc != null){
System.err.println("CANCELLING");
bc.cancel(true);
}
}
But it doesn't throw InterrupttedExeption (In which I might have Choice to close Bluetooth thread) and after research I found that waiting on Socket doesn't work on interrupt.
Any help on this?
Thanks
Got Solution After Some Research.
I just added new task to call notifier.acceptAndOpen();
And added method to close Bluetooth notifier.
public class BluetoothController extends Task<Void> {
private final ObservableList<Item> items = FXCollections.observableArrayList();
public ObservableList<Item> getItems() {
return items;
}
StreamConnectionNotifier notifier;
#Override
protected Void call() throws Exception {
try {
BluetoothConnectionTask bct = new BluetoothConnectionTask(items);
new Thread(bct).start();
Thread.sleep(2000);
notifier = bct.getNotifier();
} catch (Exception e) {
e.printStackTrace();
return null;
}
return null;
}
public void cancelandExit() {
try {
if (notifier != null) {
notifier.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
Here is new task for blocking call
public class BluetoothConnectionTask extends Task<Void>{
private StreamConnectionNotifier notifier;
private StreamConnection connection;
private ObservableList<Item> items = FXCollections.observableArrayList();
public StreamConnection getConnection() {
return connection;
}
public StreamConnectionNotifier getNotifier() {
return notifier;
}
public BluetoothConnectionTask(ObservableList<Item> is){
items = is;
}
#Override
protected Void call() throws Exception {
try {
LocalDevice local = LocalDevice.getLocalDevice();
try {
local.setDiscoverable(DiscoveryAgent.GIAC);
} catch (BluetoothStateException e) {
}
UUID uuid = new UUID(80087355); // "04c6093b-0000-1000-8000-00805f9b34fb"
String url = "btspp://localhost:" + uuid.toString() + ";name=RemoteBluetooth";
notifier = (StreamConnectionNotifier) Connector.open(url);
} catch (Exception e) {
e.printStackTrace();
return null;
}
connection = notifier.acceptAndOpen();
InputStream inputStream = connection.openInputStream();
BufferedReader bReader = new BufferedReader(new InputStreamReader(inputStream));
String lineRead = bReader.readLine();
connection.close();
inputStream.close();
notifier.close();
LocalDevice local = LocalDevice.getLocalDevice();
local.setDiscoverable(DiscoveryAgent.NOT_DISCOVERABLE);
JSONParser parser = new JSONParser();
Object obj = parser.parse(lineRead);
JSONArray array = (JSONArray) obj;
ItemDAO idao = new ItemDAO();
array.stream().map((o) -> (String) o).forEach((stringObj) -> {
String barcode = (String) stringObj;
Item i = idao.getItemByBarCode(barcode);
System.err.println("Adding Item "+i.getName());
items.add(i);
});
System.out.println("AFTER DATA RECIEVED");
return null;
}
}
Now for cancelling closing my bluetooth thread I am calling cancelandExit() after window is closed.

Spring Data MongoDB - class cast exception when persisting a List

i am using Spring-Batch with the MongoDbWriter.
So we use Spring-Data-MongoDB and when the ItemWriter is called a Class-Cast-Exception is thrown:
10:40:13.795 [jobLauncherTaskExecutor-1] DEBUG o.s.b.c.r.dao.JdbcJobExecutionDao - Truncating long message before update of JobExecution: JobExecution: id=0, version=1, startTime=Wed Jun 17 10:40:01 CEST 2015, endTime=Wed Jun 17 10:40:13 CEST 2015, lastUpdated=Wed Jun 17 10:40:13 CEST 2015, status=FAILED, exitStatus=exitCode=FAILED;exitDescription=java.lang.ClassCastException: com.mongodb.BasicDBObject cannot be cast to com.mongodb.BasicDBList
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeInternal(MappingMongoConverter.java:384)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.write(MappingMongoConverter.java:353)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.write(MappingMongoConverter.java:78)
at org.springframework.data.mongodb.core.MongoTemplate.toDbObject(MongoTemplate.java:809)
at org.springframework.data.mongodb.core.MongoTemplate.doSave(MongoTemplate.java:962)
at org.springframework.data.mongodb.core.MongoTemplate.save(MongoTemplate.java:911)
at org.springframework.batch.item.data.MongoItemWriter.doWrite(MongoItemWriter.java:128)
at org.springframework.batch.item.data.MongoItemWriter$1.beforeCommit(MongoItemWriter.java:156)
at org.springframework.transaction.support.TransactionSynchronizationUtils.triggerBeforeCommit(TransactionSynchronizationUtils.java:95)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCommit(AbstractPlatformTransactionManager.java:928)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:740)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:726)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:150)
at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:271)
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:77)
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:368)
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215)
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144)
at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:257)
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:198)
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148)
at org.springframework.batch.core.job.AbstractJob.handleStep(AbstractJob.java:386)
at org.springframework.batch.core.job.SimpleJob.doExecute(SimpleJob.java:135)
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:304)
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:135)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
, job=[JobInstance: id=0, version=0, Job=[NBO.READER.]], jobParameters=[{}]
We use spring-data-mongodb-1.7.0.RELEASE, but i think there is a bug:
the "doSave" method in MongoTemplate calls toDbObject and this method returns allways a BasicDBObject except it is a String. So when i save a List this method returns a BasicDBObject...
private <T> DBObject toDbObject(T objectToSave, MongoWriter<T> writer) {
if (!(objectToSave instanceof String)) {
DBObject dbDoc = new BasicDBObject();
writer.write(objectToSave, dbDoc);
return dbDoc;
} else {
try {
return (DBObject) JSON.parse((String) objectToSave);
} catch (JSONParseException e) {
throw new MappingException("Could not parse given String to save into a JSON document!", e);
}
}
}
After this, the write()-Method of MappingMongoConverter is called and throws the exception, because:
if (!handledByCustomConverter && !(dbo instanceof BasicDBList)) {
typeMapper.writeType(type, dbo);
}
but it is not a BasicDBList, because of the toDbObject-Method.
Then the writeInternal-Method is called and there:
if (Collection.class.isAssignableFrom(entityType)) {
writeCollectionInternal((Collection<?>) obj, ClassTypeInformation.LIST, (BasicDBList) dbo);
return;
}
This makes boom^^
It seems that the toDbObject-Method is wrong? Is that a bug?
Greetings
A workaround is to override the MongoTemplate-Class:
public class MongoHack extends MongoTemplate
{
public MongoHack(MongoDbFactory mongoDbFactory)
{
super(mongoDbFactory);
// TODO Auto-generated constructor stub
}
#Override
protected <T> void doSave(String collectionName, T objectToSave, MongoWriter<T> writer)
{
this.assertUpdateableIdIfNotSet(objectToSave);
maybeEmitEvent(new BeforeConvertEvent<T>(objectToSave));
DBObject dbDoc = this.toDbObject(objectToSave, writer);
maybeEmitEvent(new BeforeSaveEvent<T>(objectToSave, dbDoc));
Object id = saveDBObject(collectionName, dbDoc, objectToSave.getClass());
populateIdIfNecessary(objectToSave, id);
maybeEmitEvent(new AfterSaveEvent<T>(objectToSave, dbDoc));
}
private void assertUpdateableIdIfNotSet(Object entity)
{
MongoPersistentEntity<?> persistentEntity = super.getConverter().getMappingContext()
.getPersistentEntity(entity.getClass());
MongoPersistentProperty idProperty = persistentEntity == null ? null : persistentEntity.getIdProperty();
if (idProperty == null || persistentEntity == null) {
return;
}
Object idValue = persistentEntity.getPropertyAccessor(entity).getProperty(idProperty);
if (idValue == null && !MongoSimpleTypes.AUTOGENERATED_ID_TYPES.contains(idProperty.getType())) {
throw new InvalidDataAccessApiUsageException(String.format(
"Cannot autogenerate id of type %s for entity of type %s!", idProperty.getType().getName(), entity
.getClass().getName()));
}
}
private <T> DBObject toDbObject(T objectToSave, MongoWriter<T> writer)
{
if (Collection.class.isAssignableFrom(objectToSave.getClass())) {
DBObject dbDoc = new BasicDBObject();
Collection<T> objects = (Collection<T>) objectToSave;
Iterator<T> iterator = objects.iterator();
while(iterator.hasNext()) {
writer.write(iterator.next(), dbDoc);
}
return dbDoc;
}
else if (!(objectToSave instanceof String)) {
DBObject dbDoc = new BasicDBObject();
writer.write(objectToSave, dbDoc);
return dbDoc;
}
else {
try {
return (DBObject) JSON.parse((String) objectToSave);
}
catch (JSONParseException e) {
throw new MappingException("Could not parse given String to save into a JSON document!", e);
}
}
}
}
That works for me ... But i don not know if that is a helpfull usecase?

DB connection getting closed while inserting record by MDB

I have created MDB to pick the message from MQ and inserting in to DB2.
I have created data sourse to get the DB connection in WAS. Its inserting message. But due to the speed of the MessageListener some messages not inserted because the connection got closed..
Please help me to handle the conction here..
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
import javax.naming.NamingException;
#MessageDriven(
activationConfig = { #ActivationConfigProperty(
propertyName = "destinationType", propertyValue = "javax.jms.Queue"), #ActivationConfigProperty(
propertyName = "destination", propertyValue = "jms/MDBQueue")
},
mappedName = "jms/MDBQueue")
public class AsyncMessageConsumerBean implements MessageListener {
// TODO Auto-generated constructor stub
private javax.naming.InitialContext ctx = null;
private javax.sql.DataSource serviceDataSource = null;
private String environment = null;
/**
* #see MessageListener#onMessage(Message)
*/
public void onMessage(Message message) {
// TODO Auto-generated method stub
System.out.println("On Message Started.....");
try{
if (message instanceof javax.jms.BytesMessage)
{
javax.jms.BytesMessage bytesMessage = (javax.jms.BytesMessage) message;
byte[] bytes = new byte[(int) bytesMessage.getBodyLength()];
bytesMessage.readBytes(bytes);
System.out.println("Reply Message");
String replyMessage = new String(bytes, "UTF-8");
System.out.println(" The message received from MQ :-----" + replyMessage);
insertMQMessage(replyMessage);
}else {
javax.jms.TextMessage TextMessage = (javax.jms.TextMessage) message;
System.out.println("----------- The text message received from UM Queue"+TextMessage.getText());
insertMQMessage(TextMessage.getText());
}
}catch (JMSException ex) {
throw new RuntimeException(ex);
}catch(Exception ex){
ex.printStackTrace();
}
}
public void insertMQMessage(String mqMessage) throws Exception
{
Statement stmtsql = null;
Connection connection = null;
try
{
connection = getDBConnection();
System.out.println("Connection Object :"+connection);
String mqMsgTrackerInsertQry = "";
System.out.println("MQ Tracker insert Query:" + mqMsgTrackerInsertQry);
stmtsql = connection.createStatement();
boolean status = stmtsql.execute(mqMsgTrackerInsertQry);
}
catch(Exception e)
{
e.printStackTrace();
throw e;
}
finally
{
if (stmtsql != null)
try {
stmtsql.close();
} catch (SQLException ignore) {
}
if (connection != null)
try {
connection.close();
} catch (SQLException ignore) {
}
}
}
private Connection getDBConnection() throws SQLException {
try {
ctx = new javax.naming.InitialContext();
serviceDataSource = (javax.sql.DataSource) ctx.lookup("jdbc/DB_DS_XA");
System.out.println("Datasource initiallised"+serviceDataSource);
} catch (NamingException e) {
System.out.println("peformanceappraisalstatus: COULDN'T CREATE CONNECTION!");
e.printStackTrace();
}
Connection connection = null;
try {
connection = serviceDataSource.getConnection();
//connection.setAutoCommit(false);
} catch (SQLException e) {
throw e;
}
return connection;
}
}