How to convert my Database class to Singleton - singleton

I'm a beginner in java and i'm practicing Singleton.
I'm trying to figure out how to convert my Database class to Singleton.
Also, part of my issue is how to use the Database class without passing the properties in the constructor.
public class Database {
public static final String DB_DRIVER_KEY = "db.driver";
public static final String DB_URL_KEY = "db.url";
public static final String DB_USER_KEY = "db.user";
public static final String DB_PASSWORD_KEY = "db.password";
private static Logger LOG = Logger.getLogger(Database.class.getName());
private static final Database theInstance = new Database();
private static Connection connection;
private static Properties properties;
private Database() {
}
public static void init(Properties properties) {
if (Database.properties == null) {
LOG.debug("Loading database properties from db.properties");
Database.properties = properties;
}
}
public static Connection getConnection() throws SQLException {
if (connection != null) {
return connection;
}
try {
connect();
} catch (ClassNotFoundException e) {
throw new SQLException(e);
}
return connection;
}
private static void connect() throws ClassNotFoundException, SQLException {
String dbDriver = properties.getProperty(DB_DRIVER_KEY);
LOG.debug(dbDriver);
Class.forName(dbDriver);
System.out.println("Driver loaded");
connection = DriverManager.getConnection(properties.getProperty(DB_URL_KEY),
properties.getProperty(DB_USER_KEY), properties.getProperty(DB_PASSWORD_KEY));
LOG.debug("Database connected");
}
/**
* Close the connections to the database
*/
public void shutdown() {
if (connection != null) {
try {
connection.close();
connection = null;
} catch (SQLException e) {
LOG.error(e.getMessage());
}
}
}
/**
* Determine if the database table exists.
*
* #param tableName
* #return true is the table exists, false otherwise
* #throws SQLException
*/
public static boolean tableExists(String tableName) throws SQLException {
DatabaseMetaData databaseMetaData = getConnection().getMetaData();
ResultSet resultSet = null;
String rsTableName = null;
try {
resultSet = databaseMetaData.getTables(connection.getCatalog(), "%", "%", null);
while (resultSet.next()) {
rsTableName = resultSet.getString("TABLE_NAME");
if (rsTableName.equalsIgnoreCase(tableName)) {
return true;
}
}
} finally {
resultSet.close();
}
return false;
}
/**
* #return the theinstance
*/
public static Database getTheinstance() {
return theInstance;
}
}

Well this little bit change into your existing class to make you understand.
public class Database {
public static final String DB_DRIVER_KEY = "db.driver";
public static final String DB_URL_KEY = "db.url";
public static final String DB_USER_KEY = "db.user";
public static final String DB_PASSWORD_KEY = "db.password";
private static Logger LOG = Logger.getLogger(Database.class.getName());
private static Database theInstance;
private static Connection connection;
private static Properties properties;
private Database() {
}
public static void init(Properties properties) {
if (Database.properties == null) {
LOG.debug("Loading database properties from db.properties");
Database.properties = properties;
}
}
public static Connection getConnection() throws SQLException {
if (connection != null) {
return connection;
}
try {
connect();
} catch (ClassNotFoundException e) {
throw new SQLException(e);
}
return connection;
}
private static void connect() throws ClassNotFoundException, SQLException {
String dbDriver = properties.getProperty(DB_DRIVER_KEY);
LOG.debug(dbDriver);
Class.forName(dbDriver);
System.out.println("Driver loaded");
connection = DriverManager.getConnection(
properties.getProperty(DB_URL_KEY),
properties.getProperty(DB_USER_KEY),
properties.getProperty(DB_PASSWORD_KEY));
LOG.debug("Database connected");
}
/**
* Close the connections to the database
*/
public void shutdown() {
if (connection != null) {
try {
connection.close();
connection = null;
} catch (SQLException e) {
LOG.error(e.getMessage());
}
}
}
/**
* Determine if the database table exists.
*
* #param tableName
* #return true is the table exists, false otherwise
* #throws SQLException
*/
public static boolean tableExists(String tableName) throws SQLException {
DatabaseMetaData databaseMetaData = getConnection().getMetaData();
ResultSet resultSet = null;
String rsTableName = null;
try {
resultSet = databaseMetaData.getTables(connection.getCatalog(),
"%", "%", null);
while (resultSet.next()) {
rsTableName = resultSet.getString("TABLE_NAME");
if (rsTableName.equalsIgnoreCase(tableName)) {
return true;
}
}
} finally {
resultSet.close();
}
return false;
}
/**
* #return the theinstance
*/
public static Database getInstance() {
if(theInstance == null){
theInstance = new Database();
}
return theInstance;
}
}

Related

Why this constructor is not intercepted by my code?

I want to write a javaagent using byte-buddy. I wan to intercept constructor of any class that is a sub class of java.sql.Connection.
my setup code:
log.info("{} profile activated", profile);
if (profile.equals("hikari")) {
startMatcher = nameStartsWith("com.zaxxer.hikari");
JDBCAPIInterceptor.profile = new HikariProfile();
} else if (profile.equals("dbcp1")) {
startMatcher = nameStartsWith("org.apache.commons.dbcp");
JDBCAPIInterceptor.profile = new DBCP1Profile();
} else if (profile.equals("dbcp2")) {
startMatcher = nameStartsWith("org.apache.commons.dbcp2");
JDBCAPIInterceptor.profile = new DBCP2Profile();
} else if (profile.equals("druid")) {
startMatcher = nameStartsWith("com.alibaba.druid.pool");
} else {
startMatcher = any();
}
new AgentBuilder.Default().type(startMatcher.and(isSubTypeOf(java.sql.Connection.class).or(isSubTypeOf(java.sql.Statement.class))))
.transform(constructorTransformer).transform(methodsTransformer).with(listener).installOn(inst);
but why constructor of org.apache.commons.dbcp2.PoolingDataSource$PoolGuardConnectionWrapper can't be intercepted while it's definitely a sub class of java.sql.Connection as it extends org.apache.commons.dbcp2.DelegatingConnection which implements java.sql.Connection?
also, my intercepting code is executed while constructor of org.apache.commons.dbcp2.DelegatingConnection being called.
public class PoolingDataSource<C extends Connection> implements DataSource, AutoCloseable {
/**
* PoolGuardConnectionWrapper is a Connection wrapper that makes sure a closed connection cannot be used anymore.
*
* #since 2.0
*/
private class PoolGuardConnectionWrapper<D extends Connection> extends DelegatingConnection<D> {
PoolGuardConnectionWrapper(final D delegate) {
super(delegate);
}
#Override
public void close() throws SQLException {
if (getDelegateInternal() != null) {
super.close();
super.setDelegate(null);
}
}
/**
* #see org.apache.commons.dbcp2.DelegatingConnection#getDelegate()
*/
#Override
public D getDelegate() {
return isAccessToUnderlyingConnectionAllowed() ? super.getDelegate() : null;
}
/**
* #see org.apache.commons.dbcp2.DelegatingConnection#getInnermostDelegate()
*/
#Override
public Connection getInnermostDelegate() {
return isAccessToUnderlyingConnectionAllowed() ? super.getInnermostDelegate() : null;
}
#Override
public boolean isClosed() throws SQLException {
return getDelegateInternal() == null || super.isClosed();
}
}
}

Kafka consumer receive null value when sending customer object

So i want to implement application which reads data from json format files. And I have created customer object for the data in json. And I want to send these object through kafka topic. So far i have successfully send String message to producer to consumer. But when i try to send object, in the consumer side, when I do .value().toString(). I got null value. The following is the code I have used:
This is producer:
public class MyProducer {
public static void main(String[] args) throws Exception {
Properties properties = new Properties();
properties.put("bootstrap.servers", "kafka.kafka-cluster-shared.non-prod-5-az-scus.prod.us.walmart.net:9092");
properties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
properties.put("value.serializer", "xxxxxxxxx.KafkaJsonSerializer");
properties.put("acks", "1");
properties.put("retries", "2");
properties.put("batch.size", "16384");
properties.put("linger.ms", "1");
properties.put("buffer.memory", "33554432");
KafkaProducer<String, pharmacyData> kafkaProducer = new KafkaProducer<String, pharmacyData>(
properties);
String topic = "insights";
//try {
Gson gson = new Gson();
Reader reader = Files.newBufferedReader(Paths.get("......./part.json"));
List<pharmacyData> pdata = new Gson().fromJson(reader, new TypeToken<List<pharmacyData>>() {}.getType());
//pdata.forEach(System.out::println);
reader.close();
//} catch (Exception e) {
//e.printStackTrace();
//}
for (pharmacyData data : pdata) {
kafkaProducer.send(new ProducerRecord<String, pharmacyData>(topic, data), new Callback() {
#Override
public void onCompletion(RecordMetadata recordMetadata, Exception e) {
if (e == null) {
System.out.println(recordMetadata.partition() + "--" + recordMetadata.serializedValueSize());
} else {
e.printStackTrace();
}
}
});
}
kafkaProducer.close();
}
}
This is the customer object class:
public class pharmacyData {
private String load_date;
private String store_nbr;
private String state;
private String pmp_flag;
private String zero_flag;
private String submit_ts;
public pharmacyData(String load_date, String store_nbr, String state, String pmp_flag, String zero_flag, String submit_ts) {
this.load_date = load_date;
this.store_nbr = store_nbr;
this.state = state;
this.pmp_flag = pmp_flag;
this.zero_flag = zero_flag;
this.submit_ts = submit_ts;
}
public String getLoad_date() {
return load_date;
}
public void setLoad_date(String load_date) {
this.load_date = load_date;
}
public String getStore_nbr() {
return store_nbr;
}
public void setStore_nbr(String store_nbr) {
this.store_nbr = store_nbr;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getPmp_flag() {
return pmp_flag;
}
public void setPmp_flag(String pmp_flag) {
this.pmp_flag = pmp_flag;
}
public String getZero_flag() {
return zero_flag;
}
public void setZero_flag(String zero_flag) {
this.zero_flag = zero_flag;
}
public String getSubmit_ts() {
return submit_ts;
}
public void setSubmit_ts(String submit_ts) {
this.submit_ts = submit_ts;
}
#Override
public String toString() {
return "pharmacyData{" +
"load_date='" + load_date + '\'' +
", store_nbr='" + store_nbr + '\'' +
", state='" + state + '\'' +
", pmp_flag='" + pmp_flag + '\'' +
", zero_flag='" + zero_flag + '\'' +
", submit_ts='" + submit_ts + '\'' +
'}';
}
}
this is the customer Serializer:
public class KafkaJsonSerializer implements Serializer {
private Logger logger = LogManager.getLogger(this.getClass());
#Override
public void configure(Map map, boolean b) {
}
#Override
public byte[] serialize(String s, Object o) {
byte[] retVal = null;
ObjectMapper objectMapper = new ObjectMapper();
try {
retVal = objectMapper.writeValueAsBytes(o);
} catch (Exception e) {
logger.error(e.getMessage());
}
return retVal;
}
#Override
public void close() {
}
}
This is the customer Deserializer:
public class KafkaJsonDeserializer implements Deserializer {
#Override
public void configure(Map map, boolean b) {
}
#Override
public Object deserialize(String s, byte[] bytes) {
ObjectMapper mapper = new ObjectMapper();
pharmacyData pdata = null;
try {
pdata = mapper.readValue(bytes, pharmacyData.class);
} catch (Exception e) {
e.printStackTrace();
}
return pdata;
}
#Override
public void close() {
}
}
This is consumer:
public class MyConsumer {
public static void main(String[] args) {
Properties properties = new Properties();
properties.put("bootstrap.servers", "kafka.kafka-cluster-shared.non-prod-5-az-scus.prod.us.walmart.net:9092");
properties.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
properties.put("value.deserializer", "xxxxxxxx.KafkaJsonDeserializer");
properties.put("group.id", "consumer-group-1");
properties.put("enable.auto.commit", "true");
properties.put("auto.commit.interval.ms", "1000");
properties.put("auto.offset.reset", "earliest");
properties.put("session.timeout.ms", "30000");
KafkaConsumer<String, pharmacyData> consumer = new KafkaConsumer<>(properties);
String topic = "insights";
consumer.subscribe(Collections.singletonList(topic));
while (true) {
ConsumerRecords<String, pharmacyData> consumerRecords = consumer.poll(100);
for (ConsumerRecord<String, pharmacyData> consumerRecord : consumerRecords) {
System.out.println(consumerRecord.key() + "--" + consumerRecord.toString());
//System.out.println(consumerRecord.offset() + "--" + consumerRecord.partition());
}
}
}
}
Can someone please help me with the issues? Thank you very much!
Problem solved:
The solution of this issue just add a default constructor as below:
public pharmacyData() {
}
See this page for more details.

DataStreamer does not work well

I'm using Ignite 2.1.0 and I create a simple program to try DataStreamer, but I offen got error like this:
"[diagnostic]Failed to wait for partition map exchange" or "Attempted to release write lock while not holding it".
I started two local nodes, one was started in windows CMD using example xml configuration and another was started in Eclipse. My code in Eclipse like this :
public class TestDataStreamer {
public static void main(String[] args) {
// TODO Auto-generated method stub
long bgn,end;
IgniteConfiguration cfg = new IgniteConfiguration();
cfg.setPeerClassLoadingEnabled(true);
Ignite ignite = Ignition.start(cfg);
CacheConfiguration<Long, Map> cacheConf = new CacheConfiguration();
cacheConf.setName("TestDataStreamer").setCacheMode(CacheMode.REPLICATED);
cacheConf.setBackups(0);
IgniteCache cache = ignite.getOrCreateCache(cacheConf);
cache.clear();
File dataFile = new File("D:/data/1503307171374.data"); //10,000,000 rows text data
bgn = System.currentTimeMillis();
try {
loadByStreamer(dataFile,ignite,"TestDataStreamer");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
end = System.currentTimeMillis();
System.out.println("---------------");
System.out.println((end-bgn)/1000.0+" s");
}
cache.destroy();
System.out.println("cache destroy...");
ignite.close();
System.out.println("finish");
}
private static void loadByStreamer(File dataFile, Ignite ignite, String cacheName) throws Exception {
IgniteDataStreamer<Long,TestObj> ds = ignite.dataStreamer(cacheName);
//ds.allowOverwrite(true);
ds.autoFlushFrequency(10000);
ds.perNodeBufferSize(4096);
BufferedReader br = new BufferedReader(new InputStreamReader(
new FileInputStream(dataFile),"UTF-8"));
String line = null;
long count = 0;
while((line=br.readLine())!=null){
ds.addData(System.currentTimeMillis(), parseData(line, Constants.DEFAULT_SEPARATOR,
"id,sn,type_code,trade_ts,bill_ts,company_code,company_name,biz_type,charge_amt,pay_mode".split(",")));
if(++count%10000==0){
System.out.println(count+" loaded...");
}
//System.out.println(count+":"+line);
}
System.out.println("flushing...");
ds.flush();
System.out.println("flushed");
br.close();
ds.close();
System.out.println("file handled...");
}
private static TestObj parseData(String data, String saperator, String[] fields){
TestObj obj = new TestObj();
if(data!=null && saperator.trim().length()>0){
String[] values = data.split(saperator);
obj.setId(values[0]);
obj.setSn(values[1]);
obj.setType_code(values[2]);
obj.setTrade_ts(values[3]);
obj.setBill_ts(values[4]);
obj.setCompany_code(values[5]);
obj.setCompany_name(values[6]);
obj.setBiz_type(values[7]);
obj.setCharge_amt(values[8]);
obj.setPay_mode(values[9]);
}
return obj;
}
}
class TestObj {
private String id;
private String sn;
private String type_code;
private String trade_ts;
private String bill_ts;
private String company_code;
private String company_name;
private String biz_type;
private String charge_amt;
private String pay_mode;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getSn() {
return sn;
}
public void setSn(String sn) {
this.sn = sn;
}
public String getType_code() {
return type_code;
}
public void setType_code(String type_code) {
this.type_code = type_code;
}
public String getTrade_ts() {
return trade_ts;
}
public void setTrade_ts(String trade_ts) {
this.trade_ts = trade_ts;
}
public String getBill_ts() {
return bill_ts;
}
public void setBill_ts(String bill_ts) {
this.bill_ts = bill_ts;
}
public String getCompany_code() {
return company_code;
}
public void setCompany_code(String company_code) {
this.company_code = company_code;
}
public String getCompany_name() {
return company_name;
}
public void setCompany_name(String company_name) {
this.company_name = company_name;
}
public String getBiz_type() {
return biz_type;
}
public void setBiz_type(String biz_type) {
this.biz_type = biz_type;
}
public String getCharge_amt() {
return charge_amt;
}
public void setCharge_amt(String charge_amt) {
this.charge_amt = charge_amt;
}
public String getPay_mode() {
return pay_mode;
}
public void setPay_mode(String pay_mode) {
this.pay_mode = pay_mode;
}
}
If stop the node started in CMD and run the program in only one node, it works well.
Is there anyone can help me?
Update jdk for both nodes to the same version, for example for 1.8.0_144(as you already have it in installed), or at least, try to update idk in eclipse to the latest of 1.7 versions, it should help.
There is a thread on Ignite user list, when guys faced pretty the same exception and updating of java version helped them to fix it.

NullPointer Exception when populating JTable

I get following error when I try to load data into JTable.
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at com.tfc.cheque.handle.dao.impl.ChequeDAOImpl.getCheques(ChequeDAOImpl.java:23)
at com.tfc.cheque.handle.ui.ChequeGUI.(ChequeGUI.java:38)
at TestChequeDAO$1.run(TestChequeDAO.java:30)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)
this is my main class:
public class TestChequeDAO {
public static void main(String[] args) throws SQLException{
DBConnection connection = new DBConnection();
connection.setUser("");
connection.setPswd("");
ChequeDAOImpl dao = new ChequeDAOImpl();
dao.setConnection(connection);
List<Cheque> cheques = dao.getCheques();
EventQueue.invokeLater(new Runnable() {
public void run() {
ChequeGUI cgui;
try {
cgui = new ChequeGUI();
cgui.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
cgui.pack();
cgui.setVisible(true);
} catch (SQLException e) {
e.printStackTrace();
}
}
});
}
}
this is my gui class:
public class ChequeGUI extends JFrame {
JTable guiTable = new JTable();
DefaultTableModel model = new DefaultTableModel(new Object[][]{},new String[]{"Name","Amount","Date"});
public ChequeGUI() throws SQLException {
guiTable.setModel(model);
add(new JScrollPane(guiTable));
//Populate Table
ChequeDAOImpl chqdi = new ChequeDAOImpl();
List<Cheque> cheques = chqdi.getCheques();
for(Cheque cq : cheques){
model.addRow(new Object[]{cq.getName(),cq.getAmount(),cq.getDate()});
}
}
}
this is where i have written the query:
public class ChequeDAOImpl implements ChequeDAO{
//DB2 connection
private DBConnection dbConnection;
public List<Cheque> getCheques() throws SQLException{
List<Cheque> cheques = new ArrayList<Cheque>();
Connection connection = dbConnection.getConnection();
try{
Statement statement = connection.createStatement();
ResultSet result = statement.executeQuery("select * from LIB.DATA");
while(result.next()) {
Cheque cheque = new Cheque();
cheque.setAmount(result.getDouble("AMOUNT"));
cheque.setDate(result.getDate("DATE"));
cheque.setName(result.getString("NAME"));
cheques.add(cheque);
for(Cheque chq : cheques){
System.out.println("Name: " + result.getString("NAME"));
System.out.println("Amount: " + result.getDouble("AMOUNT"));
System.out.println("Date: " + result.getDate("DATE"));
}
}
}catch(Exception exception){
exception.printStackTrace();
}finally{
connection.close();
}
return cheques;
}
public DBConnection getConnection() {
return dbConnection;
}
public void setConnection(DBConnection connection) {
this.dbConnection = connection;
}
}
You need to initialize DBConnection dbConnection, and that much depends on a way how your application works

REST Web Service using Java and Jersey API: Unable to Read data from DB

I am creating a REST Web Service using Java and Jersey API. The basic REST service works fine,but when I add in a DB connection it gives me a Class Not Found Exception and a SQL Exception - No driver found. I have included the ojdbc6.jar file in the Eclipse build path. Using the same code if I create a Java application it runs fine.
I have added my code below. Can some one plz suggest something.
EDIT: I included the jar file in the WEB-INF lib directory. But when I try to execute the code I get the following error: HTTP Status 405 - Method Not Allowed
public class Note {
private int noteId;
private String content;
private Date createdDate;
public Note() {}
public Note(int noteId, String content, Date createdDate) {
this.noteId = noteId;
this.content = content;
this.createdDate = createdDate;
}
public int getNoteId() {
return noteId;
}
public void setNoteId(int noteId) {
this.noteId = noteId;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Date getCreatedDate() {
return createdDate;
}
public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
}
#Override
public String toString() {
return "Note [content=" + content + ", createdDate=" + createdDate
+ ", noteId=" + noteId + "]";
}
}
public class NoteDAO {
DatabaseAccess data;
Connection connection;
public NoteDAO()
{
try {
data = new DatabaseAccess();
connect();
} catch (SQLException e) {
e.printStackTrace();
}
}
private void connect() throws SQLException
{
try
{
data.connect();
connection = data.connection;
}
catch (SQLException e)
{
e.printStackTrace();
}
}
public Note getNoteById(int id)
{
PreparedStatement prepStmt = null;
try {
String cSQL = "SELECT * FROM NOTE WHERE NOTEID = 12 ";
prepStmt = connection.prepareStatement(cSQL);
prepStmt.setInt(1, id);
ResultSet result = prepStmt.executeQuery();
Note note = new Note();
while (result.next())
{
note.setNoteId(result.getInt(1));
note.setContent(result.getString(2));
note.setCreatedDate( (Date) new java.util.Date(result.getDate(3).getTime()));
}
return note;
} catch (SQLException e) {
e.printStackTrace();
prepStmt = null;
return null;
}
}
}
#Path("/notes")
public class Notes {
#Context
UriInfo uriInfo;
#Context
Request request;
NoteDAO dao = new NoteDAO();
#Path("{note}")
#GET
#Produces(MediaType.APPLICATION_XML)
public Note getNote(
#PathParam("note") String idStr) {
int id = Integer.parseInt(idStr);
Note note = dao.getNoteById(id);
if(note==null)
throw new RuntimeException("Get: Note with " + id + " not found");
return note;
}
public class DatabaseAccess {
Connection connection = null;
public void connect() throws SQLException
{
String DRIVER = "oracle.jdbc.driver.OracleDriver";
String URL = "jdbc:oracle:thin:#xx.xxx.xx.xxx:1521:XXXX";
String UserName = "username";
String Password = "password";
try
{
Class.forName(DRIVER);
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
try
{
connection = DriverManager.getConnection(URL,UserName,Password);
}
catch (SQLException e)
{
e.printStackTrace();
}
}
public void disconnect() throws SQLException
{
connection.close();
}
}
If you are using datasources that are managed by the application server, you need to put the ojdbc6.jar library inside the lib folder of your application server.
On JBoss for example, it would be $JBOSS_HOME/server/default/lib.
This is required, because in such case, the datasource is being build when the server starts and independently from your application, which means the server cannot use your application JARs.
If, however, you are pooling the connections yourself, you need to make sure, that the ojdbc6.jar is inside the lib folder of your application WAR archive.