I have this working java code that serve as the "datasource":
public final class PMF {
static Driver driver = null;
static String url = "jdbc:jiql://local";
static Properties props = new Properties();
static {
String password = "jiql";
String user = "admin";
props.put("user",user);
props.put("password",password);
try {
Class clazz = Class.forName("org.jiql.jdbc.Driver");
driver = (Driver) clazz.newInstance();
} catch (Exception e){
e.printStackTrace();
}
}
public static Connection get() {
try{
return driver.connect(url,props);
} catch (java.sql.SQLException e){
e.printStackTrace();
}
return null;
}
}
When I tried to adapt this code for Spring with the code below:
jdbc.properties
jdbc.driverClassName=org.jiql.jdbc.Driver
# development
jdbc.url=jdbc:jiql://local
jdbc.username=admin
jdbc.password=jiql
applicationContext.xml
<!-- placeholders -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations" value="/WEB-INF/jdbc.properties"/>
</bean>
<!-- data source -->
<bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.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}"/>
</bean>
The "datasource" gets null when I do this in the DAO:
#Autowired
private DataSource dataSource;
What could be causing the datasource to be null?
It looks like it was a DAO issue and not JDBC issue. I re-created the app using Spring STS and everything went working.
Related
I am getting this error from this line of code - 'ContextHolder.getContext().getBean(org.apache.tomcat.jdbc.pool.DataSource.class)' sometimes (not all the time).
Most of the time when it gets this error, the program retries after few minutes and recovers.
The snippet of the code from where it is coming :
import javax.sql.DataSource;
......
public class DAOUtil
{
public final static Connection getOracleConnection( ) throws DAOException
{
DataSource dataSource = ContextHolder.getContext().getBean(org.apache.tomcat.jdbc.pool.DataSource.class);
try
{
return dataSource.getConnection();
}
catch ( SQLException e )
{
throw new DAOException( "failed to get connection from data source",e );
}
}
......
}fr
In the Spring context this org.apache.tomcat.jdbc.pool.DataSource bean is described as :
<bean id="projDataSource" class="org.apache.tomcat.jdbc.pool.DataSource"
destroy-method="close" lazy-init="true">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" ref="projDsUrl"/>
<property name="username"
value="#{props[T(daffel.digital.web.Constants).PROPS_DB_USERNAME]}"/>
<property name="password" ref="decryptedPwd"/>
<property name="initialSize" value="5"/>
<property name="maxActive" value="10"/>
<property name="maxIdle" value="5"/>
<property name="minIdle" value="2"/>
<property name="maxWait" value="10000"/>
<property name="validationInterval" value="10000"/>
<property name="validationQuery" value="select 1 from dual"/>
<property name="testOnBorrow" value="true"/>
</bean>
This getOracleConnection( ) method is being called in try-with-resource way:
try (Connection connection = DAOUtil.getOracleConnection();
PreparedStatement stmt = connection.prepareStatement
( GET_QUERY );
ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
//do something
}
} catch (SQLException e) {
String msg = "Query failed: " + GET_QUERY;
LOG.error(msg, e);
throw new DAOException(msg, e);
}
Any insight?
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 am using Spring JDBC template for establishing the connection with the database. The password is in the encrypted format and want to decrypt it with the help of JDBC template. In order to implement the same, I came to know that I have to override "DriverManagerDataSource" I tried to implement the same but have not succeeded.
<bean id="dataSource"
class="MyclassName">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
public class MyclassName extends DriverManagerDataSource {
#Override
public String getPassword() {
String password = super.getPassword();
//External API decryption call
EncrypterClassName encrypterClassName = new EncrypterClassName();
return encrypterClassName.decrypt(password);
}
}
I know I have to change the <property name="password" value="${jdbc.password}" to call the class I have implemented but not sure How to do the same.
Thank you.
I've written my own ProperyPlaceholderConfigurer which is invoked whenever a variable has to be replaced.
jdbc.password={base64}yourEncryptedSecret
import java.io.IOException;
import sun.misc.BASE64Decoder;
public class PropertyPlaceholderConfigurer
extends org.springframework.beans.factory.config.PropertyPlaceholderConfigurer {
#Override
protected String convertPropertyValue(final String originalValue) {
String cryptString = "{base64}";
if (originalValue.startsWith(cryptString)) {
BASE64Decoder decoder = new BASE64Decoder();
String decodedPassword = null;
try {
decodedPassword = new String(decoder.decodeBuffer(originalValue.substring(cryptString.length())));
} catch (IOException e) {
e.printStackTrace();
}
return decodedPassword;
}
return originalValue;
}
}
Hi im new to this Spring , MVC and JdBC support.
I want to be able to connect to a mysql database..but when i run my web it returns null. Below codes i believe should be easy,What am i missing here ? Thanks for all replies
Below is my error when try to query the URL
java.lang.NullPointerException
com.simple.myacc.dao.JdbcContactDao.findAll(JdbcContactDao.java:55)
com.simple.myacc.ContactController.getAll(ContactController.java:44)
My spring.xml
.....
<context:component-scan base-package="com.simple.myacc" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/webcontact" />
<property name="username" value="root" />
<property name="password" value="password" />
</bean>
<bean id="jdbcContactDao" class="com.simple.myacc.dao.JdbcContactDao">
<property name="dataSource" ref="dataSource" />
</bean>
My JdbcContactDao
public class JdbcContactDao {
protected static Logger logger = Logger.getLogger("service");
private DataSource dataSource;
private JdbcTemplate jdbcTemplate;
public JdbcContactDao() {
}
public List<Contact> findAll() {
String sql = "select * from contact";
List<Contact> contacts = new ArrayList<Contact>();
List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql);
for (Map rs : rows) {
Contact contact = new Contact();
contact.setId((Integer) rs.get("id"));
contact.setFirstname((String) rs.get("firstname"));
contact.setLastname((String) rs.get("lastname"));
contact.setEmail((String) rs.get("email"));
contact.setPhone((String) rs.get("phone"));
contacts.add(contact);
}
return contacts;
}
#Resource(name = "dataSource")
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
} }
My controller , some part of it
#RequestMapping(value="/contact/list2",method = RequestMethod.GET)
public String getAll(ModelMap model) {
dao=new JdbcContactDao();
List<Contact> contacts = dao.findAll();
// Attach persons to the Model
model.addAttribute("contacts", contacts);
return "contact.list";
}
This is the line that says the NULL
List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql);
A common idiom when using the JdbcTemplate class is to configure a DataSource in your Spring configuration file, and then dependency inject that shared DataSource bean into your DAO classes; the JdbcTemplate is created in the setter for the DataSource.
private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
You can read more on this here
Your code will look like this
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/webcontact" />
<property name="username" value="root" />
<property name="password" value="password" />
You don't need this
<bean id="jdbcContactDao" class="com.simple.myacc.dao.JdbcContactDao">
<property name="dataSource" ref="dataSource" />
Instead do this
#Autowired
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
and annotate your JdbcContactDao class with #Repository
I think that should work
You have your dataSource and your JdbcContactDAO bean configured in the config file.
So in the same way you need to inject the jdbcContactDAO bean into your Controller.
<bean id="myController" class="mypath.MyController">
<property name="dao" ref="jdbcContactDao"/>
</bean>
And in your controller....
public JdbcContactDao dao;
#Resource(name="dao")
public void setDao(JdbcContactDao dao){
this.dao = dao;
}
#RequestMapping(value="/contact/list2",method = RequestMethod.GET)
public String getAll(ModelMap model) {
List<Contact> contacts = dao.findAll();
// Attach persons to the Model
model.addAttribute("contacts", contacts);
return "contact.list";
}
I'm guessing line 55 of JdbcContactDao is this one List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql); You declare jdbcTemplate, but never give it a value and it's also not annotated for injection, so it's always going to be null. So, when you attempt to use it, you will get the NPE.
Had a similar problem was connecting to old tables using java/jdbc
String sql = "select user_name from table"
jdbc.queryForList(sql);
queryReturnList = jdbc.queryForList(sql);
for (Map mp : queryReturnList){
String userName = (String)mp.get("user_name");
}
userName was always null. looking through the map of returned values found that the map was not using user_name but a label set up on the table of "User Name" Had to have DBA's fix. Hope this helps
I would just like to ask how can i setup a simple mail server and be able to send an email. Im using apache tomcat 6.0 as my localhost server and spring framework+jsp as well. I'm quite new on this. So if someone can give a nice tutorial, it will be of great help. thanks
Below is how you would get the spring configuration. probably applicationContext-mail.xml. Import that into applicationContext.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"autowire="byName">
default-autowire="byName">
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="${mail.host}" />
<property name="port" value="${mail.port}" />
<property name="username" value="${mail.username}" />
<property name="password" value="${mail.password}" />
</bean>
<bean id="freemarkerConfiguration"
class="org.springframework.ui.freemarker.FreeMarkerConfigurationFactoryBean">
<property name="templateLoaderPath" value="/WEB-INF/templates" />
</bean>
<!-- KINDLY MAINTAIN ALPHABETICAL ORDER THIS LINE ONWARDS -->
<bean id="notificationService" class="com.isavera.service.NotificationServiceImpl"
scope="prototype">
<property name="mailSender" ref="mailSender" />
<property name="freemarkerConfiguration" ref="freemarkerConfiguration" />
<property name="freemarkerTemplate" value="accountInformation.ftl" />
<property name="fromAddress" value="info#apnagenie.com" />
<property name="subject" value="Your account information" />
</bean>
Below is the NotificationServiceImpl
public class NotificationServiceImpl implements NotificationService, Runnable {
private boolean asynchronous = true;
private JavaMailSender mailSender;
private Configuration freemarkerConfiguration;
private String freemarkerTemplate;
private Map<String, Object> attributes;
private String deliveryAddress;
private String[] deliveryAddresses;
private String fromAddress;
private String subject;
private SimpleMailMessage message;
private MimeMessage mimeMessage;
public void deliver() {
message = new SimpleMailMessage();
if (getDeliveryAddresses() == null) {
message.setTo(getDeliveryAddress());
} else {
message.setTo(getDeliveryAddresses());
}
message.setSubject(subject);
message.setFrom(fromAddress);
// Merge the model into the template
final String result;
try {
result = FreeMarkerTemplateUtils.processTemplateIntoString(freemarkerConfiguration.getTemplate(appendApplicationName(freemarkerTemplate)), attributes);
message.setText(result);
if (asynchronous) {
Thread emailThread = new Thread(this);
emailThread.start();
} else {
run();
}
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
}
}
}