On production environment I got following error.
org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is java.sql.SQLException: Cannot create PoolableConnectionFactory (The Network Adapter could not establish the connection)
When I connect through toad, it said ORA-12541 no listener error. The issue resolved after restart of linstener.
But the actual issue may be that lot of connections opened by the web application and it is not closing that. Following are my code and configuration.
I am using EcllipseLink, dbcp2 for connections
<persistence-unit name="persistance-unit" transaction-type="RESOURCE_LOCAL">
<class>com.company.model.Characteristic</class>
...
<!--more classes -->
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="eclipselink.weaving" value="false"/>
</properties>
</persistence-unit>
dbcp2 settings
<bean id="datasource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="maxIdle" value="10" />
<property name="maxTotal" value="200" />
<property name="maxWaitMillis" value="60000" />
<property name="validationQuery" value="select 1 from dual" />
<property name="validationQueryTimeout" value="10" />
<property name="testOnBorrow" value="true" />
<property name="testWhileIdle" value="true" />
<property name="timeBetweenEvictionRunsMillis" value="30000" />
<property name="minEvictableIdleTimeMillis" value="60000" />
<property name="numTestsPerEvictionRun" value="5" />
<property name="defaultAutoCommit" value="true" />
</bean>
Connection Factory
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="persistance-unit"/>
<property name="dataSource" ref="datasource"/>
<property name="jpaVendorAdapter">
<bean id="jpaAdapter" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="database" value="ORACLE"/>
</bean>
</property>
</bean>
Transaction Management
Abstract GenericDao
public abstract class GenericDao<T> implements IGenericDao<T> {
#PersistenceContext
protected EntityManager entityManager
private Class<T> type
public GenericDao() {
Type t = getClass().getGenericSuperclass()
ParameterizedType pt = (ParameterizedType) t
type = (Class) pt.getActualTypeArguments()[0]
}
#Override
public T save(final T t) {
this.entityManager.persist(t)
return t
}
public def saveObj(def t) {
try {
this.entityManager.persist(t)
}catch(e){
log.info("Error occured: ", e)
}
return t
}
#Override
public void delete(final Object id) {
this.entityManager.remove(this.entityManager.getReference(type, id))
}
#Override
public T find(final Object id) {
return (T) this.entityManager.find(type, id)
}
#Override
public T update(final T t) {
return this.entityManager.merge(t)
}
#Override
public def executeNamedQuery(String namedQueryName, Map<String, Object> queryParams)
{
List results = null
try {
Query query = entityManager.createNamedQuery(namedQueryName)
if (queryParams) {
addPrametersToQuery(query, queryParams)
}
results = query.getResultList()
} catch (NoResultException e) {
} catch (Exception e) {
log.error("Error occured: ", e)
throw e
}
return results
}
}
Dao component using that Generic Dao
#Component("characteristicDao")
class CharacteristicDao extends GenericDao<Characteristic> implements ICharacteristicDao {
public def getCharacteristics(String name){
log.info("Entering getCharacteristics")
Characteristic characteristic = (PrmCharacteristic) executeQueryWithSingleResult("select b from Characteristic b where b.name=:name", [name:name])
log.info("Exiting getCharacteristics")
return characteristic
}
}
I use CharacteristicDao component to interact with database. Similarly I have other dao also. I have just given one example.
I use #Transactional in service for the transaction. Any master can help me please what I am doing wrong.
Related
How can i handle exceptions from Spring context .
Consider the context
<bean id="dataSource" class="oracle.jdbc.pool.OracleDataSource">
<property name="URL" value="jdbc:oracle:thin:#localhost:1521/xe" />
<property name="user" value="abc" />
<property name="password" value="abc" />
</bean>
<bean id="abc" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" >
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="default" />
<property name="persistenceXmlLocation" value="classpath*:META-INF/abc-persistence.xml" />
</bean>
And am loading context in main method
public static void main(String[] args) {
ApplicationContext applicationContext = null;
try {
applicationContext = new ClassPathXmlApplicationContext("/META-INF/spring/test.xml");
} catch (Exception e) {
System.out.println("Exception caugtht " + e);
}
}
Lets say database is down .now when i load context exceptions are not caught in catch block. Is there any way to handle this ?
I've been trying to deploy my project on my tomcat server but apparently, every time I try to start the server, I get this error in my catalina logs:
Exception encountered during context initialization - cancelling refresh attempt
org.springframework.beans.factory.BeanCreationException: Error creating bean with name
'mnpTranslationServiceImpl' defined in URL [file:/opt/tomcat/webapps/axis2/WEB-INF/springjdbc.xml]:
Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'mnpTranslationDAO' of bean class [com.e_horizon.jdbc.mnpTranslation.mnpTranslationServiceImpl]:
Bean property 'mnpTranslationDAO' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
here is my bean.xml which i named springjdbc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://192.168.XX.X1:3306/msdp" />
<property name="user" value="root" />
<property name="password" value="ehorizon" />
<property name="minPoolSize" value="1" />
<property name="maxPoolSize" value="500" />
<property name="numHelperThreads" value="5" />
<property name="initialPoolSize" value="2" />
<property name="autoCommitOnClose" value="true" />
<property name="idleConnectionTestPeriod" value="60" />
<property name="maxIdleTime" value="1200" />
<property name="acquireRetryAttempts" value="2" />
</bean>
<bean id="dataSourceHD" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://192.168.XX.X2:3306/hd" />
<property name="user" value="teligent" />
<property name="password" value="teligent" />
<property name="minPoolSize" value="1" />
<property name="maxPoolSize" value="500" />
<property name="numHelperThreads" value="5" />
<property name="initialPoolSize" value="2" />
<property name="autoCommitOnClose" value="true" />
<property name="idleConnectionTestPeriod" value="60" />
<property name="maxIdleTime" value="1200" />
<property name="acquireRetryAttempts" value="2" />
</bean>
<bean id="mpp2SubscribersDAO" class="com.e_horizon.jdbc.mpp2Subscriber.Mpp2SubscribersDAO">
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
<bean id="mpp2SubscribersService"
class="com.e_horizon.jdbc.mpp2Subscriber.Mpp2SubscribersServiceImpl">
<property name="mpp2SubscribersDAO">
<ref bean="mpp2SubscribersDAO" />
</property>
</bean>
<bean id="mnpTranslationDAO" class="com.e_horizon.jdbc.mnpTranslation.mnpTranslationDAO">
<property name="dataSource">
<ref bean="dataSourceHD" />
</property>
</bean>
<bean id="mnpTranslationServiceImpl" class="com.e_horizon.jdbc.mnpTranslation.mnpTranslationServiceImpl">
<property name="mnpTranslationDAO">
<ref bean="mnpTranslationDAO" />
</property>
</bean>
`
Here's the DAO file which the error says as not writable:
package com.e_horizon.jdbc.mnpTranslation;
import java.util.HashMap;
import java.util.Map;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
import com.e_horizon.www.jdbc.common.BaseDAO;
public class mnpTranslationDAO extends BaseDAO {
private SimpleJdbcInsert jdbcCall;
public static String TABLE = "MNP_TRANSLATION";
public static String FIELD_MSISDN = "msisdn";
public static String FIELD_ROUTING_NUMBER = "routing_number";
public static String FIELD_LAST_UPDATE = "last_update";
public static String FIELD_ACTION = "action";
protected RowMapper getObjectMapper () {
return new mnpTranslationMapper();
}
public void save (mnpTranslation mnp) {
this.jdbcCall = this.getSimpleJdbcInsert().withTableName(TABLE);
Map<String, Object> parameters = new HashMap<String, Object>();
parameters.put(FIELD_MSISDN, mnp.getMsisdn());
parameters.put(FIELD_ROUTING_NUMBER, mnp.getRouting_number());
parameters.put(FIELD_LAST_UPDATE, mnp.getLast_update());
parameters.put(FIELD_ACTION, mnp.getAction());
jdbcCall.execute(parameters);
}
}
Adding my model which contains the setters and getters (mnpTranslation.java):
package com.e_horizon.jdbc.mnpTranslation;
import java.sql.Timestamp;
public class mnpTranslation {
private String msisdn;
private String routing_number;
private Timestamp last_update;
private String action;
public void setMsisdn (String msisdn) {
this.msisdn = msisdn;
}
public String getMsisdn () {
return this.msisdn;
}
public void setRouting_number (String routing_number) {
this.routing_number = routing_number;
}
public String getRouting_number () {
return this.routing_number;
}
public void setLast_update (Timestamp last_update) {
this.last_update = last_update;
}
public Timestamp getLast_update () {
return this.last_update;
}
public void setAction (String action) {
this.action = action;
}
public String getAction () {
return this.action;
}
}
[edit] I'm adding the rest of my java files so you could see more what I'm dealing with right now. Thanks a lot for checking this.
mnpTranslationService.java:
package com.e_horizon.jdbc.mnpTranslation;
public abstract interface mnpTranslationService {
public abstract void save (mnpTranslation mnp);
}
mnpTranslationServiceImpl.java:
package com.e_horizon.jdbc.mnpTranslation;
public class mnpTranslationServiceImpl {
private mnpTranslationDAO mnpTranslationDAO;
public void save (mnpTranslation mnp) {
this.mnpTranslationDAO.save(mnp);
}
}
mnpTranslationMapper.java:
package com.e_horizon.jdbc.mnpTranslation;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;
public class mnpTranslationMapper implements RowMapper {
public Object mapRow (ResultSet result, int dex) throws SQLException {
mnpTranslation mnp = new mnpTranslation();
mnp.setMsisdn(result.getString("msisdn"));
mnp.setRouting_number(result.getString("routing_number"));
mnp.setLast_update(result.getTimestamp("last_update"));
mnp.setAction(result.getString("action"));
return mnp;
}
}
Please let me know if there's anything else you need to see. I'd gladly post it right away. Any help will be much appreciated.
The error message states that the problem is with your mnpTranslationServiceImpl class.
See error message
Bean property 'mnpTranslationDAO' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
I am facing problem in multi data source connection with spring, one of the transaction is working, but other one is not working. please help.
***********Data Source 1 start************
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="database1.ds" />
<property name="persistenceUnitName" value="database1" />
<property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
<property name="persistenceXmlLocation" value="classpath:jpa-persistence.xml" />
</bean>
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="ORACLE" />
<property name="showSql" value="false" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" p:entityManagerFactory-ref="entityManagerFactory" />
***********Data Source 1 end************
***********Data Source 2 start************
<bean id="entityManagerFactory2"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="database2.ds" />
<property name="persistenceUnitName" value="database2" />
<property name="jpaVendorAdapter" ref="jpaVendorAdapter2" />
<property name="persistenceXmlLocation" value="classpath:jpa-persistence.xml" />
</bean>
<bean id="jpaVendorAdapter2
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="ORACLE" />
<property name="showSql" value="false" />
</bean>
<bean id="transactionManager2" class="org.springframework.orm.jpa.JpaTransactionManager"
p:entityManagerFactory-ref="entityManagerFactory2" />
***********Data Source 2 end************
<context:component-scan base-package="com.wmi.lakshya" annotation-config="true" scope-resolver="org.springframework.context.annotation.Jsr330ScopeMetadataResolver"/>
<tx:annotation-driven />
<cache:annotation-driven />
Entity Manager class
#Repository
#Scope("singleton")
public class EntityManagerImpl implements EntityManagerGenerator {
#PersistenceContext(unitName = "database1",type=PersistenceContextType.EXTENDED)
private EntityManager entityManager;
#PersistenceContext(unitName = "database2",type=PersistenceContextType.EXTENDED)
private EntityManager entityManager2;
#Override
public EntityManager getEntityManager() {
try {
if (isUser1()) {
return entityManager;
}
return entityManager2;
} catch (Exception e) {
return entityManager;
}
}
}
#Transactional(value ="transactionManager")
public Query createNativeQuery(String sqlString) {
return entityManager.createNativeQuery(sqlString);
}
#Transactional(value ="transactionManager2")
public Query createNativeQuery1(String sqlString) {
return entityManager1.createNativeQuery(sqlString);
}
javax.persistence.TransactionRequiredException: Executing an
update/delete query
#Component
#Scope("prototype")
public class UserDAO extends AbstractDAO<User> {
/**
*
*/
private static final Logger LOGGER = Logger.getLogger(UserDAO.class);
/**
*
*/
protected UserDAO() {
super(User.class);
}
public void resetFailAttempts(String userName){
// em is entity manager class
em.createNativeQuery("update OMS_USER_MASTER set fail_attempts = 0 where login_id = :loginId ")
.setParameter(QueryParameters.LOGIN_ID, userName)
.executeUpdate();
}
}
Datasource is switched based on the condition, when connecting with datasource 1 is working, but not for datasource2.
I have two transaction managers defined in my context file as follows
<tx:annotation-driven transaction-manager="firstTransactionManager" />
<bean id="secondDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="---" />
<property name="url" value="datasource1" />
<property name="username" value="----" />
<property name="password" value="----" />
</bean>
<bean id="firstTransactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="firstDataSource" />
<qualifier value="firstTxManager"/>
</bean>
<bean id="secondTransactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="secondDataSource" />
<qualifier value="secondTxManager"/>
</bean>
<bean id="firstDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="---" />
<property name="url" value="datasource2" />
<property name="username" value="---" />
<property name="password" value="---" />
</bean>
And I my class definitions are as follows
#Transactional("firstTransactionManager")
public class JdbcMain {
#Autowired
private static DataSource dataSource;
public DataSource getDataSource() {
return dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public static void main(String args[]){
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
TransactionExample example = (TransactionExample) ctx.getBean("transExample");
example.create();
}
}
And my example class is as follows:
#Transactional("secondTransactionManager")
public void create(DataSource dataSource2) {
try {
this.jdbcTemplate = new JdbcTemplate(dataSource2);
String sql = "insert into testtable values (?,?)";
getJdbcTemplate().update(sql,1,"1244343");
String marksSql="insert into testtable values (?,?)";
int i=2/0; //added to depict roll back behaviour of the transaction when exception occurs
getJdbcTemplate().update(marksSql,2,"sujay");
System.out.println("transaction committed");
} catch (RuntimeException e) {
throw e;
}
}
But the second transaction manager doesn't seem to work and the transaction is not rolled back (The first insert is executed). Can you provide me an idea.
I have two Quartz (1.8.3) jobs, configured via Spring (2.5.6), one of them writes (send) to database, and one reads from it (check).
<bean id="scheduleFactory"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="Check"/>
<ref bean="Send"/>
</list>
</property>
</bean>
<bean id="Send" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
<bean class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="StatusMonitor" />
<property name="targetMethod" value="sendMessage" />
</bean>
</property>
<property name="cronExpression" value="0 0/1 * * * ?" />
</bean>
<bean id="Check" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
<bean class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="StatusMonitor" />
<property name="targetMethod" value="checkAndUpdateStatus" />
</bean>
</property>
<property name="cronExpression" value="30 0/1 * * * ?" />
</bean>
Transaction manager is set up:
<tx:annotation-driven transaction-manager="TransactionManager"/>
In both jobs I explicitly run read/write operations in transactions like this:
#Override
public synchronized void sendMessage() {
try {
TransactionTemplate tt = new TransactionTemplate(ptm);
tt.execute(new TransactionCallbackWithoutResult() {
#Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
...
statusDAO.update(status);
...
}
});
log.info("Status was updated");
} catch (Exception e) {
...
}
}
where ptm is a TransactionManager bean, injected via Spring.
I see "Status was updated" record in logs, but when I read this record from transactional read method it is outdated sometimes. Moreover, when I use an SQL editor to read this record it is outdated too.
I don't understand, why transactions dont work in this case, do you have any ideas?
Thanks.
For anyone that might be interested. This worked for me
<bean name="applicationDataCollectorControllerJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="org.mypckage.controller.jobs.ApplicationDataCollectorController" />
<property name="jobDataAsMap">
<map>
<!--<entry key="timeout" value="1" />-->
<entry key="genericService" value-ref="genericService" />
<entry key="applicationDataCollectorService" value-ref="applicationDataCollectorService" />
<entry key="transactionManager" value-ref="transactionManager" />
</map>
</property>
</bean>
--- in the scheduler bean---
#Override
protected void executeInternal(JobExecutionContext ctx) throws JobExecutionException {
getApplicationDataCollectorService().collectData(transactionManager);
}
----In the applicationDataCollectorService bean-----
public void collectData( org.springframework.transaction.jta.JtaTransactionManager transactionManager) {
try {
this.transactionManager = transactionManager;
testTransactionalSave();
} catch (Exception e) {
BUSY = false;
e.printStackTrace();
}
}
}
private void testTransactionalSave() throws Exception {
TransactionTemplate tt = new TransactionTemplate(transactionManager);
tt.execute(new TransactionCallbackWithoutResult() {
#Override
protected void doInTransactionWithoutResult(TransactionStatus ts) {
try {
ApplicationParameter appPara = null;
List<ApplicationParameter> appParaList = genericService.getListFromHQL("select o from ApplicationParameter as o order by o.id desc", false);
if (appParaList != null) {
if (appParaList.size() > 0) {
appPara = (ApplicationParameter) appParaList.get(0);
appPara.setLastBankStatementMailNum(appPara.getLastBankStatementMailNum() + 10);
appPara = (ApplicationParameter) genericService.mergeObject(appPara);
System.out.println(" num is now = " + appPara.getLastBankStatementMailNum());
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
}
Note: dont forget to declare transactionManager as private properties in both beans with public setter and getter for spring to wire it up. Any Questions? yemiosigbesan#gmail.com