Cannot get datasource in static Java method - java

I'm trying to access Oracle datasource from CDI bean.
import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.annotation.Resource;
import javax.faces.bean.ViewScoped;
import javax.inject.Named;
import javax.sql.DataSource;
#Named("ParentIDNameResolveController")
#ViewScoped
public class ParentIDNameResolve implements Serializable
{
// Call the Oracle JDBC Connection driver
#Resource(name = "jdbc/Oracle")
private static DataSource ds;
// Get the ID if the parent
public static int ParentId(int chieldId) throws SQLException
{
int ParentId = 0;
if (ds == null)
{
throw new SQLException("Can't get data source");
}
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs;
try
{
conn = ds.getConnection();
ps = conn.prepareStatement("SELECT COMPONENTID, FKCOMPONENTID, COMPONENTSTATSID from COMPONENT where COMPONENTID = ?");
ps.setLong(1, chieldId);
rs = ps.executeQuery();
while (rs.next())
{
ParentId = rs.getInt("FKCOMPONENTID");
}
}
finally
{
if (ps != null)
{
ps.close();
}
if (conn != null)
{
conn.close();
}
}
return ParentId;
}
// Get Parent Name
public static String ParentName(int ParentId) throws SQLException
{
String ParentName = null;
if (ds == null)
{
throw new SQLException("Can't get data source");
}
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs;
try
{
conn = ds.getConnection();
ps = conn.prepareStatement("SELECT COMPONENTSTATSID, NAME from COMPONENTSTATS where COMPONENTSTATSID = ?");
ps.setLong(1, ParentId);
rs = ps.executeQuery();
while (rs.next())
{
ParentName = rs.getString("NAME");
}
}
finally
{
if (ps != null)
{
ps.close();
}
if (conn != null)
{
conn.close();
}
}
return ParentName;
}
}
Unfortunately when I reference datasource from static Java method I get this error:
Can't get data source
I'm not sure is it possible to access datasource from static Java method. Is there a way to fix this problem?

It's not sure that your container will inject anything with adnotation #Resource to a static field or a static method. Try to rethink your class and maybe make it as #ApplicationScoped then you will also have only one instance per application.
Here are little changes to your class:
#Named("ParentIDNameResolveController")
#javax.enterprise.context.ApplicationScoped // not from javax.faces.bean
public class ParentIDNameResolve implements Serializable
{
// Call the Oracle JDBC Connection driver
#Resource(name = "jdbc/Oracle")
private DataSource dataSource;
/*
Add getter/setter for DataSource
*/
public DataSource getDataSource() {
return this.ds;
}
public void DataSource setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
/* Change method signature to non static */
public int ParentId(int chieldId) throws SQLException
{
DataSource ds = getDataSource();
// your code here
return ParentId;
}
/* Change method signature to non static */
public String ParentName(int ParentId) throws SQLException
{
DataSource ds = getDataSource();
// your code here
return ParentName;
}
}
Next you can use it in your code also as injected object and You can be sure that DataSource wont' be null but if it will be - check is it properly defined as DataSource in configuration files.

Related

Apache DBCP and Oracle Transparent Application continuity

We have an older application that can't failover when one node of our Oracle RAC goes down. It seems it uses an older version of org.apache.commons.dbcp.BasicDataSource. I can make this work when I use UCP from Oracle but when I use the apache version the app dies as soon as I shut down the node of the RAC it is connected to. Am I missing something or does it not work with Apache DBCP? Thanks
Here is my code.
import org.apache.commons.dbcp.BasicDataSource;
import java.io.PrintStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class BasicDB{
final static String DB_URL ="jdbc:oracle:thin:user/password#pdb_tac";
final static String driverClassName = "oracle.jdbc.replay.OracleDataSourceImpl";
private void pressAnyKeyToContinue()
{
System.out.print("Press any key to continue...");
try { System.in.read(); }
catch(Exception e) { e.printStackTrace(); }
}
public String getInstanceName(Connection conn) throws SQLException {
PreparedStatement pstmt = conn.prepareStatement("select instance_name from v$instance");
String r = new String();
for(ResultSet result = pstmt.executeQuery(); result.next(); r = result.getString("instance_name")) {
}
pstmt.close();
return r;
}
private void doTx(Connection c, int numValue) throws SQLException {
String updsql = "UPDATE test SET v=UPPER(v) WHERE id=?";
PreparedStatement pstmt = null;
pstmt = c.prepareStatement(updsql);
c.setAutoCommit(false);
for(int i = 0; i < numValue; ++i) {
pstmt.setInt(1, i);
pstmt.executeUpdate();
}
c.commit();
pstmt.close();
}
public static void main(String[] args) throws SQLException {
Connection conn = null;
int numValue = 5000;
;
try {
BasicDataSource bods = new BasicDataSource();
bods.setUrl(DB_URL);
bods.setDriverClassName(driverClassName);
bods.setDefaultAutoCommit(false);
BasicDB self = new BasicDB();
conn = bods.getConnection();
String var10001 = self.getInstanceName(conn);
var10000.println("Instance Name = " + var10001);
System.out.println("Performing transactions");
self.pressAnyKeyToContinue();
self.doTx(conn, numValue);
var10001 = self.getInstanceName(conn);
var10000.println("Instance Name = " + var10001);
} catch (Exception var8) {
var8.printStackTrace();
}
}
}
Ok, so it has to do with using the DataSource instead of the DataDriver class. I have run into another error so will create a new question for that.

CallableStatement never ends when it is executed for first time

I am currently working with ejb3, Java 1.8, jboss and oracle project. I am having a issue with CallableStatement. I have a procedure that is called when a CSV file is processed. When the procedure it called for the first time most of the time it never ends. But when a reuse the procedure again it work perfectly. Could you please give me any advice how to deal with this situation?
cStmt = prepareCall("{call CPRPA_TPT_PRICE_CALC.tpt_data_import(?,?)}");
import java.sql.CallableStatement;
import java.sql.SQLException;
import java.sql.Connection;
import java.util.HashMap;
import javax.persistence.EntityManager;
import org.hibernate.Session;
import org.hibernate.engine.spi.SessionImplementor;
public abstract class ProcDao extends BaseDao {
/** Callable statement cache */
private HashMap<String, CallableStatement> callableStatementCache = null;
/** Session */
private Session session = null;
/**
* Constructor
*
* #param entityManager Entity manager
*/
public ProcDao(EntityManager entityManager) {
super(entityManager);
}
/**
* Creates a callable statement and stores it in the callable statement cache.
*
* #param sqlString SQL statement
* #return Native query
* #throws SQLException Database error
*/
#SuppressWarnings({"deprecation"})
protected CallableStatement prepareCall(String sqlString) throws SQLException {
if (callableStatementCache == null) {
callableStatementCache = new HashMap<String, CallableStatement>();
}
CallableStatement callableStatement = callableStatementCache.get(sqlString);
if (callableStatement == null) {
if (session == null) {
session = (Session) entityManager.getDelegate();
}
SessionImplementor sessionImplementor = (SessionImplementor)session;
Connection conn = sessionImplementor.connection();
callableStatement = conn.prepareCall(sqlString);
callableStatementCache.put(sqlString, callableStatement);
}
return callableStatement;
}
/** Closes the cached callable statements and connections. */
public void close() {
if (callableStatementCache != null && callableStatementCache.size() > 0) {
for (CallableStatement callableStatement : callableStatementCache.values()) {
try {
Connection connection = callableStatement.getConnection();
callableStatement.close();
connection.close();
} catch (Throwable ex) {
ex.printStackTrace();
}
}
callableStatementCache.clear();
}
if (session != null) {
if(session.isOpen()){
session.disconnect();
}
session = null;
}
}
}
import java.sql.CallableStatement;
import java.sql.SQLException;
import javax.persistence.EntityManager;
public class ImportPriceLevelProcedureManagerDao extends ProcDao {
/**
* Constructor
*
* #param entityManager {#link EntityManager}
*/
public ImportPriceLevelProcedureManagerDao(EntityManager entityManager) {
super(entityManager);
}
public void invokeImportPriceFromTempTableProcedure(int sessionId, String userID) throws DataException {
CallableStatement cStmt = null;
try {
cStmt = prepareCall("{call CPRPA_TPT_PRICE_CALC.tpt_data_import(?,?)}");
cStmt.setInt(1, sessionId);
cStmt.setString(2, userID);
cStmt.execute();
} catch (SQLException e) {
throw new DatabaseException("Database exception occured!" + e);
} catch (RuntimeException e) {
throwDataException(e);
} finally {
try {
cStmt.close();
} catch (SQLException e) {
throw new DatabaseException("Unable to release the Callable Statement");
}
}
}
#Stateful(name = "xxxx/ImportPriceLevelProcedureManager")
public class ImportPriceLevelProcedureManagerBean extends ProcManagerBean<ImportPriceLevelProcedureManagerDao> implements ImportPriceLevelProcedureManager, ImportPriceLevelProcedureManagerLocal {
/** Entity-Manager */
#PersistenceContext(type = PersistenceContextType.TRANSACTION, unitName = "xxxx")
private EntityManager entityManager;
/**
* Set entity manager for testing purpose
*
* #param entityManager {#link EntityManager}
*/
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
/** {#inheritDoc} */
#Override
public void invokeImportPriceFromTempTableProcedure(int sessionId, String userID) throws DataException {
getDao().invokeImportPriceFromTempTableProcedure(sessionId, userID);
}

java ResultSet and statement issue

i don't understand why my variable state cannot be resolved.
i'm in a java Mysql project.
Here is the Commands class code:
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
public class Commands {
public Commands() throws SQLException{
Connection conn = DbConn.getInstance();
Statement state = conn.createStatement();
}
public String getList(){
System.out.println("Here is a List of our Products:");
// Get list from db
ResultSet result = state.executeQuery("SELECT * FROM products");
ResultSetMetaData resultMeta = result.getMetaData();
// Display the List
System.out.println("List displayed");
return null;
}
}
Here is the DbConn class code:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DbConn {
private static String url = "jdbc:mysql://localhost:3306/myDB";
private static String user = "root";
private static String passwd = "";
private static Connection connect;
// create new instance if not exists
public static Connection getInstance(){
if(connect == null){
try {
connect = DriverManager.getConnection(url, user, passwd);
} catch (SQLException e) {
e.printStackTrace();
}
}
return connect;
}
}
My code is not finished yet, but the message come on this line:
ResultSet result = state.executeQuery("SELECT * FROM products");
My Eclipse editor says this message state cannot be resolved
Any idea?
That is a matter of scope. You define the variable here
public Commands() throws SQLException{
Connection conn = DbConn.getInstance();
Statement state = conn.createStatement();
}
And that is the only place the variable is visible - in the constructor. Define it in the class and initialize it in the constructor:
private Connection conn = null;
private Statement state = null;
public Commands() throws SQLException{
conn = DbConn.getInstance();
state = conn.createStatement();
}
Declare "State" outside of that constructor.
Connection conn = null;
Statement state = null;
public Commands() throws SQLException{
conn = DbConn.getInstance();
state = conn.createStatement();
}

How to update a table using values from java ArrayList?

I'm working on my application where I want to update my table after email has been sent. I created function that connect sql database and java, also in other class I created function that updates table but what I need is these two classes together. I want to use my array-list after execution for updating of my table.
Here is my code for connection and sending emails:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
public class TestSendEmails {
private String emailTo;
private String emailSubject;
private String emailBody;
private String emailAttachments;
private Integer RecordId;
public TestSendEmails(){
}
public TestSendEmails(String emailTo, String emailSubject, String emailBody, String emailAttachments, Integer RecordId){
super();
this.emailTo = emailTo;
this.emailSubject = emailSubject;
this.emailBody = emailBody;
this.emailAttachments = emailAttachments;
this.RecordId = RecordId;
}
public String getEmailTo(){
return emailTo;
}
public void setEmailTo(String emailTo){
this.emailTo = emailTo;
}
public String getEmailSubject(){
return emailSubject;
}
public void setEmailSubject(String emailSubject){
this.emailSubject = emailSubject;
}
public String getEmailBody(){
return emailBody;
}
public void setEmailBody(String emailBody){
this.emailBody = emailBody;
}
public String getEmailAttachments(){
return emailAttachments;
}
public void setEmailAttachments(String emailAttachments){
this.emailAttachments = emailAttachments;
}
public Integer getRecordId(){
return RecordId;
}
public void setRecordId(Integer RecordId){
this.RecordId = RecordId;
}
}
class TestSendEmailD{
private Connection con;
private static final String GET_EMAILS = "Select* From Emails";
private void connect() throws InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException{
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver").newInstance();
con = DriverManager.getConnection("jdbc:sqlserver://100.000.000.00\\:3333;databaseName=Test;user=mmmm;password=1234");
}
public List<TestSendEmails> getTestSendEmails() throws Exception{
connect();
PreparedStatement ps = con.prepareStatement(GET_EMAILS);
ResultSet rs = ps.executeQuery();
List<TestSendEmails> result = new ArrayList<TestSendEmails>();
while(rs.next()){
result.add(new TestSendEmails(rs.getString("emailTo"), rs.getString("emailSubject"),rs.getString("emailBody"),rs.getString("emailAttachments",rs.getInt("RecordId"))));
}
disconnect();
return result;
}
private void disconnect() throws SQLException{
if(con != null){
con.close();
}
}
}
class EmailSender{
private Session session;
private void init(){
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.host", "100.000.000.00");
props.put("mail.smtp.port", "678");
session = Session.getInstance(props,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("test#gmail.com", "123");
}
});
}
public void sendEmail(TestSendEmails s) throws MessagingException{
init();
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("test#gmail.com"));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(s.getEmailTo().replace(";", ",")));
message.setSubject(s.getEmailSubject());
message.setText(s.getEmailBody());
message.setContent(s.getEmailBody(),"text/html");
Transport.send(message);
System.out.println("Done");
}
public void sendEmail(List<TestSendEmails> emails) throws MessagingException{
for(TestSendEmails TestSendEmails:emails ){
sendEmail(TestSendEmails);
}
}
}
Here is my Update code:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.util.Date;
public class UpdateEmail {
public static Connection getConnection() throws Exception {
String driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
String url = "jdbc:sqlserver://100.000.000.00\\:3333;databaseName=Test";
String username = "mmmm";
String password = "1234";
Class.forName(driver);
Connection conn = DriverManager.getConnection(url, username, password);
return conn;
}
public static void main(String[] args) throws Exception {
java.util.Date date = new Date();
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = getConnection();
String query = "update Emails set SentOn = ? where Id = ? ";
pstmt = conn.prepareStatement(query); // create a statement
pstmt.setTimestamp(1, new java.sql.Timestamp(date.getTime()));
pstmt.setInt(2, 200); // In this line I want to use my array-list to update my table.
pstmt.executeUpdate(); // execute update statement
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
} finally {
pstmt.close();
conn.close();
}
}
}
I'm not sure if I have to create new connection for my update in my second program and where I should implement my update code. If you know what I should change please let me know. Thanks in advance.
Main.java code:
import java.util.List;
public class Main {
public static void main(String[] args) throws Exception {
TestSendEmailD dao=new TestSendEmailD();
List<TestSendEmails> list=dao.getTestSendEmails();
EmailSender sender=new EmailSender();
sender.sendEmail(list);
}
}
I guess you have an ArrayList() called yourList. The following code goes before
String query ...
StringBuilder ids = "";
String prefix ="";
for (Integer id: yourList) {
append(prefix);
prefix = ",";
ids.append(String.valueOf(id));
}
change your query to:
String query = "update Emails set SentOn =? where Id in (" + ids.toString() + ")";
and send only the SentOn as parameter:
pstmt.setTimestamp(1, new java.sql.Timestamp(date.getTime()));
Connection conn = null;
PreparedStatement pstmt = null;
conn = getConnection();
java.util.Date date = new Date();
message.setFrom(new InternetAddress("test#gmail.com"));
String query = "update Emails set SentOn = ? where Id = ? ";
pstmt = conn.prepareStatement(query); // create a statement
String str[]=String.valueOf(s.getRecordId()).split(";");//id1;id;id3;....
for(int i=0;i<str.length();i++)
{
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(s.getEmailTo().replace(";", ",")[i]));
message.setSubject(s.getEmailSubject());
message.setText(s.getEmailBody());
message.setContent(s.getEmailBody(),"text/html");
Transport.send(message);
System.out.println("Done");
pstmt.setTimestamp(1, new java.sql.Timestamp(date.getTime()));
pstmt.setInt(2, str[i]); // In this line I want to use my array-list to update my table.
pstmt.executeUpdate(); // execute update statement
System.out.println(str[i]+" "+s.getEmailTo().replace(";", ",")[i]+" "+new java.sql.Timestamp(date.getTime()));//to check whether its working or not.
}
Its exactly not an exact answer. check whether its working or not. Here you must take care of exceptions also. I didn't written that code here.

Mysql database Exception

Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Type mismatch: cannot convert from java.sql.Statement to com.mysql.jdbc.Statement
i am a beginner in java i am trying to use mysql database i have downloaded mysql-connector-java-5.1.23-bin.jar file from mysql.com and i have added this jar file to in my build path of my project but there is an error in the following code
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Type mismatch: cannot convert from java.sql.Statement to com.mysql.jdbc.Statement
package com.example.demo;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.Statement;
public class DBConnect
{
private static final String userName = "root";
private static final String userpwd = "sverma";
private static final String CONN_STR = "jdbc:mysql://localhost:3306/phpweb_db";
public static void main(String[] args) throws SQLException
{
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try
{
DriverManager.getConnection(CONN_STR, userName, userpwd);
st=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
rs = st.executeQuery("select * from user");
rs.last();
System.out.println("No of rows: " + rs.getRow());
// System.out.println("Connected Successfully...");
}
catch (SQLException e)
{
System.err.println(e);
}
finally
{
if (rs != null)
{
rs.close();
}
if (st != null)
{
st.close();
}
if (conn != null)
{
conn.close();
}
}
}
}
Wrong classes
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.Statement;
should be
import java.sql.Connection;
import java.sql.Statement;
In fact, java decouples everything from a specific database engine. One never should need an import of MySQL (or ProgressSQL or ...) classes.
To have those classes available at run-time, the first thing after the try, before getting the connection would be:
Class.forName("com.mysql.jdbc.Driver");
This technique would allow reading all strings from a configuration file, and writing database independent code.
Missing: conn = ...
conn = DriverManager.getConnection(CONN_STR, userName, userpwd);
package com.example.demo;
import java.sql.*;
public class DBConnect
{
private static final String userName = "root";
private static final String userpwd = "sverma";
private static final String CONN_STR = "jdbc:mysql://localhost:3306/phpweb_db";
public static void main(String[] args) throws SQLException
{
Connection conn;
Statement st;
ResultSet rs;
try
{
Class.forName("com.mysql.jdbc.Driver");
DriverManager.getConnection(CONN_STR, userName, userpwd);
st=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
rs = st.executeQuery("select * from user");
rs.last();
System.out.println("No of rows: " + rs.getRow());
// System.out.println("Connected Successfully...");
}
catch (SQLException e)
{
System.err.println(e);
}
finally
{
if (rs != null)
{
rs.close();
}
if (st != null)
{
st.close();
}
if (conn != null)
{
conn.close();
}
}
}

Categories