Google

Dec 24, 2013

What skills are you expected to have as a senior Java developer?

You need at least 4-6 projects under your belt to become a so called "senior" developer. Some achieve it quicker than the others. It is harder to quantify by number of years because some gain real  3-5 year hands-on experience, whilst others repeat the same year 2 to 3 times. Here is the list of skills you need to have accomplished in my view to become a senior Java developer

Skill #1: Good "software craftsmanship" skills. In other words have good handle on the 16 technical key areas listed below. You should have the ability to ask the right questions (e.g. should I use aspect oriented programming (i.e. AOP) here?, should  I favor optimistic or pessimistic locking here? should the method call made within a transactional context?) and solve problems (e.g. memory leaks, thread safety, SQL injection attacks, performance, etc)  relating to these 16 technical key areas.

What are these 16 key areas? 

  1. Language Fundamentals (LF)
  2. Specification Fundamentals (SF)
  3. Platform Fundamentals (PF)
  4. Design Considerations  (DC)
  5. Design Patterns (DP)
  6. Concurrency Management (CM)
  7. Performance Considerations  (PC)
  8. Memory/Resource Considerations  (MC)
  9. Transaction Management  (TM)
  10. Security (SE)
  11. Scalability  (SC)
  12. Best Practices (BP)
  13. Coding (CO)
  14. Exception Handling (EH)
  15. Software Development Processes (SDP)
  16. Quality of Service  (QoS)


Skill #2: Ability to look at things from both business and technical perspective. It is also imperative to have good communication, analytical, interpersonal, and researching skills to transform the business requirements into conceptual design and detailed technical design with pros and cons, risk assessment, tactical vs strategical approach, UML diagrams, ER (Entity Relationship) diagrams, class diagrams and OO concepts.

Transform functional and non functional requirements like logging, auditing, capacity planning, load balancing, instrumentation (to ensure 24 x 7 availability), disaster recovery and archival strategies of data (e.g. regular back ups) to build a robust system that meets the SLAs (Service Level Agreement).


Skill #3: Good working experience of conceptual architectures. Only experience will tell what works well in which environment. In other words you need to have the ability to look at the overall system at a 100 feet without delving into its details. Understand the environments (e.g. skill-sets of the developers, business unit structure,  tool sets used,  existing capabilities, etc ),  and the team culture to decide what will work and what will not. Don't just read an article off the internet and think that it can be easily applied to your environment. For example, adopting agile development practices or service oriented architectures has its own challenges and need full co-operation and commitment from the senior management. It will not work in every environment. It requires gradual and progressive changes to get there. Sometimes you need to quickly change tactics based on the challenges you face.



Skill #4: Right soft skills and attitude to thrive in a team environment. Don't wait for things to happen but make things happen by taking initiatives and communicating your thoughts more effectively with the can do attitude and right emotions to work with others as a team.

For example, sometimes the business requirements might not be clear. As a senior developer, you need to have the right soft skills to take initiatives to clarify and document the business requirements. Software development is like fitting all the puzzles (e.g. 16 key areas and non functional requirements) together like a puzzle. It is hard to have all the technical skills under the sun. So, you need to collaboratively work with the multi-disciplinary teams to tap into others' skills get the job done.  It is important to learn to handle criticisms and avoid "I know it all" attitude.


Skill #5: Using the right tools for productivity gains.  For example, I have blogged about using Notepad++ and excel to manipulate data and construct complex SQL queries quickly. I have also blogged about many other tools for debugging Java apps, testing RESTful web services, and web applications. Unix is very powerful to automate repetitive tasks.

Skill #6: Taking pride in your work and invest in continuously learning. You will be continuously re-factoring and improving your work. You will know what to look for when reviewing others' code. You will have better diagnostic skills. You will know how to avoid the common pitfalls. You will be motivated to invest more time in your learning and sharing your experience through blogging, helping fellow professionals via industry specif forums, and writing articles. You will be opinionated as to what new features or improvements you would like to be added in the future releases.


As a seasoned developer, you will know how to take a project through the full SDLC activities as doer and facilitator.

Note: I have blogged about some of the 16 key areas and tools for improving productivity. These links can be found on the RHS panel. My book entitled "How to open more doors as a software engineer?" covers all the 16 key areas and many insights in to expanding your horizons as a senior Java developer.



Labels: ,

Dec 23, 2013

How to get an entry level Java developer job?

Entry level Java developers and career changers get caught in the vicious cycle where "you can't get a job without some hands-on experience, but the employers are not keen to hire you without some experience". Employers are looking for entry level developers who can start contributing from the day they join. This does not mean that employers are not going to provide you training and support, but rather looking for skills outside academic qualifications like -- working independently, quick learner, passion for the chosen profession, understanding of the industry, ability to communicate your thoughts/capabilities and some much needed  "hands-on experience". There is no other magic formula. Most employers don't care where you got that experience from.

So, if you are stuck in this vicious cycle, the key is to get some experience to break this cycle via self-taught projects, open-source contribution, and volunteer work in Java (e.g. charity organizations and local community projects).  It does not matter what avenue you take, and every experience counts. You need to demonstrate your passion & understanding of the chosen profession, and ability to work independently and as a team. Here are some step by step guide to get the ball rolling.

Things that do not make a real difference in securing a job:
  1. Thinking that piling up of your certifications can help.
  2. Thinking that a post-graduate qualification can increase your chances.
  3. Thinking that reading a Java book from cover to cover can help. It is very important to learn the fundamentals, but mix learning the fundamentals with gaining the much needed hands-on experience. Can you drive a car by just learning how the controls work?
Things you should do to make a break as a Java developer:
Only way to learn to drive a car is by getting behind the wheels. So, 3 things you should do in a nutshell.
  1. Invest in improving your job hunting skills encompassing interviewing, networking, and resume writing skills.
  2. Keep applying for jobs via both published & hidden job markets.
  3. Follow the tips outlined below to enhance your hands-on experience while keeping at points 1 & 2.
All the above 3 points should go hand-in-hand. That is your full-time or part-time job of "finding a job"
Getting the much needed hands-on experience

Tip #1: Java is very accessible and all the following are available for free. The steps you take may slightly vary depending on your familiarity with Java and its tools.
  1. A computer -- desk top or lap top.
  2. Download latest version of Java (JDK and JRE).
  3. Download latest version of eclipse IDE.
  4. Dowload Tomcat or JBoss to deploy your applications.
  5. Download and install MySQL database. All non trivial applications need information to be persisted to a database.
  6. Set up Maven as a build and dependency management tool so that you can download sought after frameworks like Spring and Hibernate.




Google search, good blogs and online tutorials are your friends in setting up the above 6 items. Even with 13+ year experience in Java, researching on Google.com is integral part of getting my job done as a Java developer. As an experienced Java developer, I can research things much faster. You will improve your researching skills with time. You will know what key words to search on. If you are stuck, ask your mentor or go to popular forums like Javaranch.com to ask your fellow Java developers.

Tip #2: Start with the basics first. Enterprise Java has hundreds of frameworks and libraries and it is easy for the beginners to get confused. Once you get to a certain point, you will get a better handle on them, but to get started, stick to the following basic steps. Feel free to make changes as you see fit.
  1. Core Java fundamentals. Write simple stand alone Java programs using OO concepts. Write unit tests with JUnit.
  2. Learn SQL and write stand alone Java programs that connect to MySQL database via JDBC.
  3. Write simple web applications using Servelts and JSPs using enterprise Java. The application needs to persist data to the MySQL database. Deploy your application to Tomcat or JBoss server and run them as an enterprise application. Use Maven for build and dependency management. 
  4. Expand your project created with JSPs, Servlets, and JDBC to use sought after frameworks. Learn the concept of "dependency injection". Start wiring up sought after frameworks like Spring. Spring is very vast, and start with spring core and spring jdbc. Spring core is used for dependency injection and Spring jdbc is to connect to databases and to execute SQL queries. 
  5. Learn the MVC (Model View Controller) design pattern for web development. Convert your JSPs and Servelts to Spring-mvc based web application.
  6. Write RESTFul web services using Spring MVC. 
  7. Get a working knowledge in HTML, JavaScript/jQuery/JSON, ajax, and CSS. This is imperative as more and more organizations are moving towards JavaScript based MVC frameworks like angularjs or backbone. These frameworks make RESTFul web service calls to get data in JSON format and populate the front end. It will be handy to learn node.js as well if time permits.
  8. Make sure that you write unit tests for your code with JUnit and mocking frameworks like Mockito.

Tip #3: Once you have some familiarity and experience with developing enterprise applications with Java, try contributing to open source projects or if your self-taught project is non trivial, try to opensource your self-taught project. You can learn a lot by looking at others' code.  

Tip #4: Look for volunteer work to enhance your hands-on experience. Don't over commit yourself. Allocate say 2 to 3 days to build a website for a charity or community organization.

Tip #5: Share your hands-on experience gained via tips 1-4 in your resume and through blogging (can be kept private initially). It is vital to capture your experience via blogging.  Improve your resume writing and interviewing skills via many handy posts found in this blog or elseware on the internet. It is essential that while you are working on the tips 1-5, keep applying for the paid jobs as well.

Tip #6: Voluntary work and other networking opportunities via Java User Groups (JUGs) and graduate trade fairs can put you in touch with the professionals in the industry and open more doors for you. The tips 1-5 will also differentiate you from the other entry level developers. My books and blog has covered lots of Java interview questions and answers. Practice those questions and answers as many employers have initial phone screening and technical tests to ascertain your Java knowledge, mainly in core Java and web development (e.g. stateless HTTP protocol, sessions, cookies, etc). All it takes is to learn 10 Q&A each day while gaining hands-on experience and applying for entry level jobs. Top 20 Java technical interview questions and answers for experienced Java developers.

Getting a good handle on  the 16 technical key areas and handy tools to improve your productivity as a Java developer are other handy links on the RHS panel of this blog.


Do you want to become a front-end developer, and confused about where to start?

The new trend is to use JavaScript based frameworks like AngularJS. So, learning JavaScript, HTML(5), and CSS is a must. AngularJS is growing fast. The current JEE standard is JSF. Newer projects are moving towards client side MVW (Model View Whatever) frameworks using AngularJS, Backbone, ExtJs, etc. If you end up enhancing an existing application, you have a good chance of working on one of the following Web frameworks JSF, Spring MVC, Struts(2), and GWT.


For learning purpose, stick to JavaScript, jQuery, CSS, HTML(5), Spring MVC and JSF.

Finding an entry level Java developer job itself a full-time job

You have the 8 hour+ work cut out for you. Regularly review your progress, and fine tune your approach. Sometimes you may require 360 degree turn (e.g. shift from piling up certifications to gaining much needed hands-on experience, shift from reading Java books from cover to cover to taking up a volunteer work, turning your job hunting from 2 hours a day to a 8 hour a day, etc ) to your approach. It is really important to do variety of things to keep it interesting and keep you motivated. It is easy to lose motivation. Share your experience with your fellow entry level Java developers. It is vital that you keep applying for a paid job whilst working on the above tips.

More on this  @ Handy tips to get some work experience on your Java/JEE CV. 

Labels: ,

Dec 22, 2013

NamedParameterStatement versus PreparedStatement

Q. When will you use NamedParameterStatement over PreparedStatement?
A.

Reason 1:  PreparedStatement uses anonymous parameters that are accessed by index, which is ok when you have 2 or 3 parameters, but for larger queries with many parameters it os more difficult to keep track of the indices. The developer has to count the number of question marks.


String sql = "select * from people where (first_name = ? or last_name = ?) and address = ?";
PreparedStatement p = con.prepareStatement(sql);
p.setString(1, name);
p.setString(2, name);
p.setString(3, address);


The above query will require you to renumber the indices, and it can be improved as shown below.

String sql = "select * from people where (first_name = ? or last_name = ?) and address = ?";
PreparedStatement p = con.prepareStatement(sql);
int i = 1;
p.setString(i++, name);
p.setString(i++, name);
p.setString(i++, address);

The NamedParameter is even more cleaner.

String sql = "select * from people where (first_name = :name or last_name = :name) and address = :address";
NamedParameterStatement p = new NamedParameterStatement(con, sql);
p.setString("name", name);
p.setString("address", address);




Reason 2: In some cases parameters make your query more readable when you have combination of parameters and database functions like getdate( ), etc. The following example is Spring jdbc based to use parameter names.

 
 
public int insertOfflineSuperEquityRequest(TradeDetail td) {

    String sql = "insert into trade_request ( account_code, source_system, reference, ext_reference," +                
    " security_code,create_date,create_id,update_date,update_id) " +
    "   values (:acc_code,'SYSTEM_A', :ref, :ext_ref, :security, getdate(), suser_name(),getdate(), suser_name())";

    //Spring JDBC Named Parameter class 
    NamedParameterJdbcTemplate npJdbcTemplate =  new NamedParameterJdbcTemplate(jdbcTemplate.getDataSource());
  
  
    Map parameters = new HashMap();
    parameters.put("acc_code", td.accountCode);
    parameters.put("ref", td.getReference());
    parameters.put("ext_ref", td.getExternalReference());
    parameters.put("security", td.getSecurityCode());
 
    
  
    int updateCount = npJdbcTemplate.update(sql, getOfflineRequestArgs(td));
    return updateCount;
}


As you can see, it has a combination of named parameters (:acc_code, :ref, :ext_ref, and security), a constant (i.e. SYSTEM_A), and Sybase database functions like getDate( ) to get current date time and   suser_name( ) to get the user id.


Labels: ,

Dec 19, 2013

JSF Composite Components for reusability

Q. Can you explain what are composite components in JSF?
A. JSF 2.0 introduced reusable components called composite components. It uses "cc" ( Composite Component)as the prefix in .xhtml files.

Q. How will you create a Composite Component in JSF 2.0 or later versions?
A. If you want to write a component say login.xhtml and call it from a page named register.xhtml, here are the basic steps.

Step 1: Define the component under
  • src/main/webapp/resources  in your war file or
  • src/main/resources/META-INF/resources  in you jar file

Let's define the login.xhtml  under src/main/webapp/resources/login-folder


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"   
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:composite="http://java.sun.com/jsf/composite"
      >
 
    <composite:interface>
 
     <composite:attribute name="userNameLabel" />
     <composite:attribute name="userNameValue" />
     <composite:attribute name="passwordLabel" />
     <composite:attribute name="passwordValue" />
        //........... 
    </composite:interface>
 
    <composite:implementation>
 
 <h:form>
 
 
  <h:panelGrid columns="2" id="textPanel">
 
   #{cc.attrs.userNameLabel} : 
   <h:inputText id="name" value="#{cc.attrs.userNameValue}" />
 
   #{cc.attrs.passwordLabel} : 
   <h:inputText id="password" value="#{cc.attrs.passwordValue}" />
 
  </h:panelGrid>
         //.... 
 </h:form>
 
    </composite:implementation>
 
</html>

Note: cc.attrs.userNameLabel refers to userNameLabel defined in the composite:interface. "cc.attrs" is an internal JSF prefix. It uses other prefixes like cc:clientId, which returns current composite component's prefix.


Step 2: Invoke the composite component from the register.xhtml page. This is what passes the  values to the components interface.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"   
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:registration="http://java.sun.com/jsf/composite/login-folder">
 
    <h:body>
 
     <h1>Composite Components in JSF 2.0</h1>
 
 <registration:login id="loginComponent"
  userNameLabel="Name" 
  userNameValue="#{user.name}" 
  passwordLabel="password" 
  passwordValue="#{user.password}"
  />
 
    </h:body>
 
</html>

Note:

The component is registered under the name "registration" prefix --> http://java.sun.com/jsf/composite/login-folder and "login-folder" tells you where to find the component under src/main/webapp/resources.

The registration:login --> registration is the prefix and login denotes look for login.xhtml under the folder src/main/webapp/resources/login-folder which is defined by the registration name space prefix in the html element.

The #{cc.clientId} value will be "loginComponent"

Step 3: #{user.name} refers to the JSF managed bean class. Where "user" is the annotated value and name is a Java class instance variable.


import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
 
@ManagedBean(name="user")
@SessionScoped
public class UserBean{
 
 public String name;
 public String password;
 
 //getter and setter methods for name and password
 
 //any action class methods
}





Search for "JSF" or click on the JSF cloud tag for more blog posts on JSF with diagrams and code snippets. JSF is kind of in a decline in favor of JavaScript based frameworks like angular-js. I have a few posts on angularjs and Javascript .  JSF mainly used for enhancing or maintaining existing applications.


Labels:

Dec 18, 2013

Configure Spring batch to persist to a database

Q. Why do you have to persist Spring batch run information to a database?
A. If you write industrial strength large batch jobs, you need to store job runs to a database so that you can monitor the jobs, restart a job, etc.


Step 1: You need to create database tables. You can find the schema inside the spring-batch-core-xxx.jar as shown below.





The tables that gets created are



Step 2: You need to have the relevant dependency jar files in addition to the spring batch jars.

org.springframework.jdbc-3.0.0.RELEASE.jar
com.springsource.com.thoughtworks.xstream-1.3.0.jar
com.springsource.org.codehaus.jettison-1.0.0.jar

commons-dbcp-1.2.2.jar

Step 3: Configure your spring config file

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:util="http://www.springframework.org/schema/util"
 xsi:schemaLocation="
  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.1.xsd
  http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd">

 <bean id="jobExplorer"
  class="org.springframework.batch.core.explore.support.JobExplorerFactoryBean"
  p:dataSource-ref="dataSource_oracle" p:tablePrefix="BATCH_" />

 <job-repository id="jobRepository" lob-handler="lobHandler"
  data-source="dataSource_oracle" transaction-manager="transactionManager"
  isolation-level-for-create="READ_COMMITTED" table-prefix="BATCH_"
  xmlns="http://www.springframework.org/schema/batch" />

 <bean id="lobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler">
  <property name="nativeJdbcExtractor">
   <bean
    class="org.springframework.jdbc.support.nativejdbc.OracleJdbc4NativeJdbcExtractor" />
  </property>
 </bean>
 <bean id="jobLauncher"
  class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
  <property name="jobRepository" ref="jobRepository" />
 </bean>
 <bean id="taskExecutor" class="org.springframework.core.task.SimpleAsyncTaskExecutor">
  <property name="concurrencyLimit" value="3" />
 </bean>
 

</beans>




Search at the top for "Spring batch" or select the "Spring batch" tag cloud for more basic and advanced posts on spring batch.

Labels:

Dec 17, 2013

Software developer productivity tip with Notepad++ to construct SQL clause or any other data conversion

Lets take a tutorial like scenario to demonstrate power of Notepad++ as a  developer productivity tool.

Q. How will you extract rule_name values from a tabular data shown below and convert it to an SQL query as shown below as well?

id  type  rule_nmae            bean_name
633 ALL  asx100_rule           SECURITY_VALIDATION
632 ALL  asx200_rule           SECURITY_VALIDATION
634 ALL  ETF_rule              SECURITY_VALIDATION
635 ALL  managed_fund_rule     SECURITY_VALIDATION

This data could com from an excel spread sheet, word document, or copied from a confluence or wiki page.

The SQL we need is:

Select * from rules_table where rule_name in ('asx100_rule', 'asx200_rule', 'ETF_rule', 'managed_fund_rule');

A. Let's see Notepad++ in action

Step 1:  Copy the data to Notepad++ and delete the header row by highlighting it and pressing the delete button.

id      type      rule_nmae   bean_name


Step 2: You need to now remove all the columns except rule_name column. To do this place the cursor LHS of  first 633 value and press    + keys together and highlight the columns you want to remove with the mouse. Do the same for the last column as well.



Step 3: Next step is to remove any leading or trailing spaces. Use regex based find and replace command. Pressing CTR+ F will bring the Find dialog . You can also select it from the  "Search" menu at the top.

In the pop up find dialog, select the "replace" tab. Enter the  find and replace value as shown below. Make sure the  "Regular expression" option and "Wrap around" check box are ticked.





Don't copy paste, but type.

Find What: [\s]+
Replace with: ,

Step 4: Remove the new line characters or carriage return by finding and replacing with the "Extended ..." option turned on as shown below.


Don't copy paste, but type.

Find What: \r
Replace with: 

Replace new line with nothing.

Step 5: You need to put a single quote (') around the entries for the SQL query. Regex is agin back to the rescue.



Don't copy paste, but type.

Find What: ([^,]*)(,?)
Replace with: '\1'\2

The parentheses '( )' are used to capture the values. and \1 and \2 represent both the captured values. The ' is add before \1 and \2. Where \1 is the value like "asx100_rule" and \2 is ",". The * means 0 or many, and  ? means 0 or 1.

You can now take the single line text and put it in your where clause. This is very handy when you have to work with larger data.

This tutorial is good for learning regular expression as well.



You may also like:

Labels: ,

Dec 15, 2013

Spring batch working with the listeners

Q. Why do you have listeners in Spring batch?
A. Reader --> to read data and Writer --> to write chunked data and processor --> to filter out records before they are passed to the ItemWriter. Filtering is an action distinct from skipping; skipping indicates that a record is invalid whereas filtering simply indicates that a record should not be written.

Listeners are events that can be executed before or after a point in time like before or after executing a step, etc.


Here is an example that uses all the listeners except for the ItemProcessListener.


package com.mysample.job;

import java.util.List;

import org.springframework.batch.core.ChunkListener;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.ItemReadListener;
import org.springframework.batch.core.ItemWriteListener;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobExecutionListener;
import org.springframework.batch.core.SkipListener;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.StepExecutionListener;

public class SampleListener implements ItemWriteListener<List<String>>, StepExecutionListener, JobExecutionListener,
  ItemReadListener<String>, ChunkListener, SkipListener<String, String> {

 @Override
 public void afterRead(String arg0) {
 }
 
 @Override
 public void beforeRead() {
 }

 @Override
 public void onReadError(Exception arg0) {
 }

 @Override
 public void afterJob(JobExecution arg0) {
 }

 @Override
 public void beforeJob(JobExecution arg0) {
 }

 @Override
 public ExitStatus afterStep(StepExecution arg0) {
  return null;
 }

 @Override
 public void beforeStep(StepExecution arg0) {
 }

 @Override
 public void afterWrite(List<? extends List<String>> arg0) {
 }

 @Override
 public void beforeWrite(List<? extends List<String>> arg0) {
 }

 @Override
 public void onWriteError(Exception arg0, List<? extends List<String>> arg1) {
 }

 @Override
 public void onSkipInProcess(String arg0, Throwable arg1) {
 }

 @Override
 public void onSkipInRead(Throwable arg0) {
 }

 @Override
 public void onSkipInWrite(String arg0, Throwable arg1) {
 }

 @Override
 public void afterChunk() {
  
 }

 @Override
 public void beforeChunk() {
 }
}


Q. Where do you declare a listener?
A. In the Spring config file.

    <job id="sampleJob" restartable="false"
  xmlns="http://www.springframework.org/schema/batch">
  <step id="sampleStep">
   <tasklet task-executor="taskExecutor">
    <chunk reader="sampleReader" writer="sampleWriter"
     commit-interval="3">
    </chunk>
    <listeners>
     <listener ref="sampleListener" />
    </listeners>
   </tasklet>
  </step>
 </job>
 
 <bean id="sampleListener" scope="step" class="com.mysample.SampleListener">
  <property name="jobId" value="#{stepExecutionContext[JOB_ID]}" />
  <property name="runDate" value="#{jobParameters['RUN_DATE']}" />
 </bean>


Q. What do you understand by the terms StepExecution, JobExecution, JobExecutionContext, and StepExecutionContext?
A. You can store data between readers and writers using StepExecution or JobExecution. For example, you may want to keep track of the failed accounts by storing them in a job control table. These accounts can be read again from the job control table and rerun in the next job run.

stepExecution.getExecutionContext().put(ValidationJobMapKey.FAILED_ACCOUNTS.name(), failedItems);
jobExecution.getExecutionContext().put(ValidationJobMapKey.JOB_INFO.name(), info);

Here is a more comprehensive sample listener code.

package com.mysample.job;

//...

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.joda.time.Instant;
import org.joda.time.Interval;
import org.joda.time.Period;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.ItemWriteListener;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.StepExecutionListener;
//....

/**
 * writes batch run data to the job control table after write and after step
 * failed accounts are stored in the stepExecution context
 */
public class SampleListener implements ItemWriteListener<TradeAccount>, StepExecutionListener {

 private static final Logger logger = LoggerFactory.getLogger(SampleListener.class);

 @Resource(name = "sampleService")
 private SampleService sampleService;

 private Long jobId;
 private Date runDate;
 private Instant startTime;

 private StepExecution stepExecution;
 
 @Override
 public void beforeWrite(List<? extends TradeAccount> items) {
  startTime = new Instant();
 }

 @Override
 public void afterWrite(List<? extends TradeAccount> items) {
  Period period = new Interval(startTime, new Instant()).toPeriod();
  logger.info("Finish call service, duration: " + getDuration(period));
  try {
   JobControlMetaData meta = new JobControlMetaData();
   meta.setJobId(this.jobId);
   meta.setJobRunDate(runDate);
   //Spring batch gives you the ExitStatus
   meta.setJobStatus(ExitStatus.COMPLETED);
   sampleService.updateJobControlTable(meta, items);
  } catch (Exception e) {
   logger.error("Failed to update job control: ", e);
  }

  logger.info("Finish write, duration: " + getDuration(new Interval(startTime, new Instant()).toPeriod()));
 }

 @Override
 /**
   * Transactions are rolleback here.
   */
 public void onWriteError(Exception exception, List<? extends TradeAccount> items) {
  logger.error("Error to process accounts: " + items);
  handleFailedAccounts(exception, items);
 }
 
 /**
  * Store failed accounts in the step execution context
  */
 private synchronized void handleFailedAccounts(Exception exception, List<? extends TradeAccount> items){
  for (TradeAccount tradeAccount : items) {
   tradeAccount.setErrorMsg(exception.getMessage());
  }
  
  @SuppressWarnings("unchecked")
  List<TradeAccount> failedItems = (List<TradeAccount>) stepExecution.getExecutionContext().get(ConstantEnum.FAILED_ACCOUNTS.name());
  if(failedItems == null) {
   failedItems = new ArrayList<TradeAccount>();
  }
  
  failedItems.addAll(items);
  
  //ConstantEnum is enum class with constant values.
  stepExecution.getExecutionContext().put(ConstantEnum.FAILED_ACCOUNTS.name(), failedItems);
 }
 
 public Long getJobId() {
  return jobId;
 }

 public void setJobId(Long jobId) {
  this.jobId = jobId;
 }

 public Date getRunDate() {
  return runDate;
 }

 public void setRunDate(Date runDate) {
  this.runDate = runDate;
 }

 @Override
 /**
  *  Write failed accounts to the job control table
  **/
 public ExitStatus afterStep(StepExecution stepExecution) {
  @SuppressWarnings("unchecked")
  List<TradeAccount> failedItems = (List<TradeAccount>) stepExecution.getExecutionContext().get(ConstantEnum.FAILED_ACCOUNTS.name());
  if(failedItems != null && failedItems.size() > 0) {
   try {
    JobControlMetaData meta = new JobControlMetaData();
    meta.setJobId(this.jobId);
    meta.setJobRunDate(runDate);
    //Spring batch gives you the ExitStatus
    meta.setJobStatus(ExitStatus.FAILED);
    sampleService.updateJobControlTable(meta, failedItems);
   } catch (Exception e) {
    logger.error("Failed to update job control: ",e);
   }
  }
  return null;
 }

 @Override
 public void beforeStep(StepExecution stepExecution) {
  this.stepExecution = stepExecution;
  //Spring allocates job ids. so get it.
  jobId = stepExecution.getJobExecution().getJobId();
  stepExecution.getExecutionContext().put(ConstantEnum.JOB_ID.name(), jobId);
 }
 
 private static String getDuration(Period period) {
  return period.getHours() + ":" + period.getMinutes() + ":" + period.getSeconds() + "." + period.getMillis();
 }
}


Labels:

Dec 12, 2013

Spring JdbcTemplate batch updates and inserts

Q. Why are batch updates faster?
A.

  • The query doesn't need to be repeatedly parsed. Parsed only once per batch.
  • The values are transmitted in one network round-trip to the server. So, only one remote call.
  • The commands can be placed inside a single transaction when run in a transnational context. 

Q. Should batch updates run within a transaction?
A. Yes.  It is important to keep in mind, that each update added to a Statement or PreparedStatement is executed separately by the database. So, to avoid some data succeeding and others failing you need to run them inside a transaction. When executed inside a transaction, either all updates succeed or all fail, leaving the data in a consistent state.

Q. What type of statement is used for the batch updates?
A. PreparedStatement.

Q. How will you perform a batch update using the Spring JdbcTemplate?
A. The example below is used for an update SQL, but it can be used in a similar fashion for inserts and deletes as well. Spring issues multiple update statements on a single PreparedStatementThere are two ways to do this.

Approach 1


package com.myapp.dao;

import org.springframework.jdbc.core.JdbcTemplate;

public class TradeDaoImpl implements TradeDao {

    @Resource(name = "jdbcTemplate")
    JdbcTemplate jdbcTemplate;

    @Override
 public int[] updateTradeStatusAndErrorMsg(final List<TradeDetail> tradeDetails) {
  
  final String UPDATE_TRADES_SQL = "UPDATE trade_table SET status=?, error=? "
                 + "  WHERE  trade_id=?"
  
  List<Object[]> updateBatchArgs = getUpdateBatchArgs(tradeDetails);
  
  int[] updateCounts = jdbcTemplate.batchUpdate(UPDATE_TRADES_SQL,updateBatchArgs);
   
 }
 
 
 private List<Object[]> getUpdateBatchArgs(List<TradeDetail> tradeDetails) {
  List<Object[]> updateBatchArgs = new ArrayList<Object[]>();
  for (TradeDetail d : tradeDetails) {
   Object[] updateArgs = new Object[3];
   updateArgs[0] = d.getStatus() != null ? d.getStatus().toString() : "";
   updateArgs[1] = d.getErrorMsg() != null ? d.getErrorMsg() : "";
   updateArgs[2] = d.getTradeId().intValue();
   updateBatchArgs.add(updateArgs);
  }
  
  return updateBatchArgs;
 }
}




Approach 2:

package com.myapp.dao;

import org.springframework.jdbc.core.JdbcTemplate;

public class TradeDaoImpl implements TradeDao {

    @Resource(name = "jdbcTemplate")
    JdbcTemplate jdbcTemplate;

    @Override
 public int[] updateTradeStatusAndErrorMsg(final List<TradeDetail> tradeDetails) {
  
  final String UPDATE_TRADES_SQL = "UPDATE trade_table SET status=?, error=? "
                 + "  WHERE  trade_id=?"
  
  //anonymous inner class is used
  int[] updateCounts = jdbcTemplate.batchUpdate(UPDATE_TRADES_SQL, new BatchPreparedStatementSetter() {

      //more control over the prepeared statement
   @Override
   public void setValues(PreparedStatement ps, int i) throws SQLException {
    TradeDetail d = tradeDetails.get(i);
    ps.setObject(1, d.getStatus() != null ? d.getStatus().toString() : TradeStatusType.ERR.toString(), Types.CHAR);
    ps.setString(2, d.getErrorMsg() != null ? d.getErrorMsg() : "");
    ps.setInt(3,d.getTradeId().intValue());
   }

   @Override
   public int getBatchSize() {
    return tradeDetails.size();
   }
  });

  return updateCounts;
   
 }
}


Labels:

Dec 11, 2013

Scalable Straight Through Processing System (OLTP) vs OLAP in Java

Large mission critical applications use Straight Through Processing, and these systems need to be highly scalable. So, when you apply for these high paying jobs, it really pays to prepare for your job interviews with the following questions and answers.

Q. What is Straight Through Processing (STP)?
A. This is the definition from INVESTOPEDIA.

"An initiative used by companies in the financial world to optimize the speed at which transactions are processed. This is performed by allowing information that has been electronically entered to be transferred from one party to another in the settlement process without manually re-entering the same pieces of information repeatedly over the entire sequence of events."

Q. How will you go about designing a STP system?
A.  Most conceptual architectures use a hybrid approach using a combination of different architectures based on the benefits of each approach and its pertinence to your situation. Here is a sample hybrid approach depicting an online trading system, which is a STP system.


The above system is designed for:
  • Placing Buy/Sell online trades real time. The trades are validated first and then sent all the way to Stock Exchange system using the FIX (Financial Information eXchange) protocol. Here some usefil links on FIX.
Are you going for programming jobs at investment banks or financial institutions? Knowing some investment and trading terms will be useful?
  • Once the trade is matched, the contract notes are asynchrnously issued via the SETTLEMENT queue, and processed by an ESB (Enterprise Service Bus) system like web Methods, Tibco, or Websophere MQ. Here are some useful links on asynchronous processing.

The above system is an operational OLTP (i.e. On-Line Transaction Processing) system. These systems are also known as STP (i.e. Straight Through Processing) system. This leads to another question.


Q. What is the difference between OLTP and OLAP?
A. OLTP stands for On-Line Transaction Processing and OLAP stands for On-Line Analytical Processing. OLAP contains a multidimensional or relational data store designed to provide quick access to pre-summarized data & multidimensional analysis. 

 
MOLAP: Multidimensional OLAP – enabling OLAP by providing cubes.
ROLAP: Relational OLAP – enabling OLAP using a relational database management system




OLTP
OLAP
Creates operational source data from transactional systems as shown in the above diagram. This data is the source of truth for many other systems.
Data comes from various OLTP data sources as shown in the above  diagram.
Transactional and normalized data is used for daily operational business activities.
Historical, de-normalized and aggregated multidimensional data is used for analysis and decision making. This is also known as for BI (i.e. Business Intelligence).
Data is inserted via short inserts and updates. The data is normally captured via user actions.
Periodic (i.e. scheduled) and long running (i.e. during off-peak) batch jobs refresh the data. Also, known as ETL process as shown in the below diagram.
The database design involves highly normalized tables.
The database design involves de-normalized tables for speed. Also, requires more indexes for the aggregated data.
Regular backup of data is required to prevent any loss of data, monetary loss, and legal liability.

Data can be reloaded from the OLTP systems if required. Hence, stringent backup is not required.
Transactional data older than certain period can be archived and purged based on the compliance requirements.
Contains historical data. The volume of this data will be higher as well due to its requirement to maintain historical data.
The typical users are operational staff.
The typical users are management and executives to make business decisions.
The space requirement is relatively small if the historical data is regularly archived.
The space requirement is larger due to the existence of aggregation structures and historical data. Also requires more spaces for the indexes.

Labels: ,

Dec 7, 2013

Beginner Spring Batch reader and writer tutorial


Step 1: You need the relevant jar files. Here is the maven pom.xml snippet


<dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-beans</artifactId>
 <version>3.1.2</version>
</dependency>
<dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-core</artifactId>
 <version>3.1.2</version>
</dependency>
<dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-context</artifactId>
 <version>3.1.2</version>
</dependency>
<dependency>
 <groupId>org.springframework.batch</groupId>
 <artifactId>spring-batch-core</artifactId>
 <version>2.1.9</version>
</dependency>
<dependency>
 <groupId>org.springframework.batch</groupId>
 <artifactId>spring-batch-infrastructure</artifactId>
 <version>2.1.9</version>
</dependency>


Step 2: Define the Spring config file spring-batch-job.xml  with repository, launcher, job, step, reader, and writer. The reader and writer are defined within chunk element with the commit-interval being the chunk size. The reader reads one item say at a time and chunk it according to the chunk size (1 in this example) and pass it to the writer as List. The concurrency limit value of 3 means 3 threads can process in parallel.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:util="http://www.springframework.org/schema/util"
 xsi:schemaLocation="
  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.1.xsd
  http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd">


 <!-- define the job repository -->
 <bean id="jobRepository"
  class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
 </bean>

 <!--define the launcher and pass the jobRepository as setter injection -->
 <bean id="jobLauncher"
  class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
  <property name="jobRepository" ref="jobRepository" />
 </bean>

 <!-- multi-threading -->
 <bean id="taskExecutor" class="org.springframework.core.task.SimpleAsyncTaskExecutor">
  <property name="concurrencyLimit" value="3" />
 </bean>

 <bean id="transactionManager"
  class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />

 <job id="simpleJob" xmlns="http://www.springframework.org/schema/batch">
  <step id="simpleStep">
   <tasklet task-executor="taskExecutor">
    <chunk reader="simpleReader" writer="simpleWriter"
     commit-interval="1">

    </chunk>
   </tasklet>

  </step>
 </job>


 <bean name="simpleReader" scope="step" class="com.myapp.SimpleReader" />

 <bean name="simpleWriter" scope="step" class="com.myapp.SimpleWriter" />

</beans>


Step 3: Define the custom reader SimpleReader. Hard coded the list to keep it simple. In real life, read from a data source like database or file. T is String here.

package com.myapp;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.NonTransientResourceException;
import org.springframework.batch.item.ParseException;
import org.springframework.batch.item.UnexpectedInputException;

public class SimpleReader implements ItemReader<String> {

 // creates an unmodifiable list
 String[] itemArray = new String[] { "Java", "Spring", "Hibernate" };
 // creates a modifiable list
 List<String> items = new ArrayList<String>(Arrays.asList(itemArray));

 @Override
 public String read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
  if (!items.isEmpty()) {
   return getNextItem();
  }
  return null;
 }

 // using items directly without lock is not thread safe
 private synchronized String getNextItem() {
  return items.remove(0);
 }



Step 4: Define the custom writer SimpleWriter. List is List. Chunked and passed to the reader.
 
package com.myapp;

import java.util.List;

import org.springframework.batch.item.ItemWriter;

public class SimpleWriter implements ItemWriter<String> {

 @Override
 public void write(List<? extends String> items) throws Exception {
  for (String item : items) {
   // prefix each tem with "my-"
   final String prefix = "My_";
   item = prefix + item;

   System.out.println(Thread.currentThread() + " writes: " +  item);
  }
 }
}


Step 5: The main class that runs as a stand-alone application.

package com.myapp;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersInvalidException;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
import org.springframework.batch.core.repository.JobRestartException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SimpleBatchTest {

 public static void main(String[] args) throws JobExecutionAlreadyRunningException, JobRestartException,
   JobInstanceAlreadyCompleteException, JobParametersInvalidException {
  ApplicationContext appContext = new ClassPathXmlApplicationContext("classpath:/job-config/spring-batch-job.xml");

  //get the launcher
  JobLauncher jobLauncher = (JobLauncher) appContext.getBean("jobLauncher");
  //get the job to run
  Job job = (Job) appContext.getBean("simpleJob");
  //run
  jobLauncher.run(job, new JobParameters());
 }
}

Output:

11:17:13.906 [main] INFO  o.s.b.c.l.support.SimpleJobLauncher - Job: [FlowJob: [name=simpleJob]] launched with the following parameters: [{}]
11:17:13.925 [main] INFO  o.s.batch.core.job.SimpleStepHandler - Executing step: [simpleStep]
Thread[SimpleAsyncTaskExecutor-2,5,main] writes: My_Java
Thread[SimpleAsyncTaskExecutor-3,5,main] writes: My_Spring
Thread[SimpleAsyncTaskExecutor-1,5,main] writes: My_Hibernate
11:17:13.989 [main] INFO  o.s.b.c.l.support.SimpleJobLauncher - Job: [FlowJob: [name=simpleJob]] completed with the following parameters: [{}] and the following status: [COMPLETED]

Running more than once can throw JobIsAlreadyRunningException. So, you need to supply different JobParameters as shown below.


JobParameters jobParameters = 
      new JobParametersBuilder()
      .addLong("time",System.currentTimeMillis()).toJobParameters();
  
jonLauncher.run(job, jobParameters);


The above was run with 3 threads and commit-interval of 1. Experiment by changing the "commit-interval" (aka chunk size) within the step and the "concurrencyLimit" within the SimpleAsyncTaskExecutor in the spring config file.


More advanced blog posts on Spring batch


Labels:

Dec 5, 2013

Performance profiling with AspectJ AOP and Spring

Q. Can you profile the following sample test class with aspectj AOP and Spring?

package com.myapp;

import java.util.concurrent.TimeUnit;

public class TestClass {
 public void testMethod1()  {
  System.out.println("executing testMethod1");
  try {
    // just delay
   TimeUnit.MILLISECONDS.sleep(100);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }
}

A. Here are the steps.

Step 1: Required libraries via maven pom.xml.

        <properties>
            <spring.version>3.0.5.RELEASE</spring.version>
        </properties>

  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-beans</artifactId>
   <version>${spring.version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-core</artifactId>
   <version>${spring.version}</version>
  </dependency>
  
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context</artifactId>
   <version>${spring.version}</version>
  </dependency>
  
  
        <!-- Spring AOP + AspectJ -->
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-aop</artifactId>
   <version>${spring.version}</version>
  </dependency>

  <dependency>
   <groupId>org.aspectj</groupId>
   <artifactId>aspectjrt</artifactId>
   <version>1.6.11</version>
  </dependency>

  <dependency>
   <groupId>org.aspectj</groupId>
   <artifactId>aspectjweaver</artifactId>
   <version>1.6.11</version>
  </dependency>




Step 2: Aspect using aspectj.

package com.myapp;

import java.util.Arrays;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class PerformanceProfilingAspect {

 @Around("execution( * com.myapp.*.* (..) )")
 public Object invoke(final ProceedingJoinPoint pjp) throws Throwable {
  
  Signature signature = pjp.getSignature();
  Object[] args = pjp.getArgs();
  String argList = Arrays.toString(args);
  System.out.println("Start executing: "+  signature.getDeclaringTypeName() + "." + signature.getName() + "(" + argList + ")");
  long s = System.nanoTime();
  
  //invoke the actual method
  Object proceed = pjp.proceed(args); 
  
  long e = System.nanoTime();
  System.out.println("Completed after: " + signature.getDeclaringTypeName() + "." + signature.getName() + "(" + argList
    + ") ended after " + ((double) (e - s)/1000000) + "ms");
  
  return proceed;

 }

}


Step 3: Spring config file test-spring-aop.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:batch="http://www.springframework.org/schema/batch"
 xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
 xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
  http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.0.xsd
   http://www.springframework.org/schema/aop 
     http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
      http://www.springframework.org/schema/context 
                           http://www.springframework.org/schema/context/spring-context-3.0.xsd
  http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

 <aop:aspectj-autoproxy />
 <context:component-scan base-package="com.myapp"/>

 <bean id="performanceProfilingAspect" class="com.myapp.PerformanceProfilingAspect" />
 <bean id="test" class="com.myapp.TestClass" />

</beans>


Step 4: the main class

package com.myapp;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AspectJAopProfilingTest {
 
 public static void main(String[] args) {
  ApplicationContext appContext = new ClassPathXmlApplicationContext(
                "classpath:/test-spring-aop.xml");

  TestClass test= (TestClass) appContext.getBean("test");
        test.testMethod1();
 }
}


Step 5: The output

Start executing: com.myapp.TestClass.testMethod1([])
executing testMethod1
Completed after: com.myapp.TestClass.testMethod1([]) ended after 121.053234ms


Labels: , , ,

Spring SimpleJdbcCall to invoke stored procedures



Q. How will you use SimpleJdbcCall  to invoke a stored procedure for example in Sybase like


CREATE PROCEDURE calculate_avail_cash_balance
(
    @p_account_code       char(6),
    @p_avail_cash_bal     money   OUTPUT
)
AS

BEGIN
    DECLARE @avail_cash_holding money,
            @minimum_cash_req       money

 SELECT  @p_avail_cash_bal = 0;  
 --  some logic to calculate available balance 
 SELECT @p_avail_cash_bal = isnull(@avail_cash_holding,0) 
                             -  isnull(@minimum_cash_req,0)  

 if(@p_avail_cash_bal < 0)
    SELECT @p_avail_cash_bal = 0.0;
END 


So, calculate the available cash balance for a given account code.

A. Here is a sample DAO class that shows SimpleJdbcCall in action.

package com.mayapp.dao;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.SqlInOutParameter;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcCall;


public class TradeDaoImpl implements TradeDao {

    @Resource(name = "myJdbcTemplate")
 private JdbcTemplate myJdbcTemplate;

    @Override
 public BigDecimal getCalculatedAvailableBalance(String accountCode) {
  SimpleJdbcCall call = new SimpleJdbcCall(
     myJdbcTemplate
)
    .withProcedureName("calculate_avail_cash_balance");

  // required to fix rounding issue
  call.addDeclaredParameter(new SqlInOutParameter("p_avail_cash_bal", java.sql.Types.DOUBLE));

  final MapSqlParameterSource params = new MapSqlParameterSource();
  params.addValue("p_account_code", accountCode);
  

  // execute the stored proc with the input parameters
  Map<String, Object> results = call.execute(params);

  Double calcAvailCashBalance = (Double) results.get("p_avail_cash_bal");

  return new BigDecimal(calcAvailCashBalance);
 }
}


If you need to provide catalog and schema values then
SimpleJdbcCall call = new SimpleJdbcCall(myJdbcTemplate)
          .withCatalogName("my_catalog")
          .withSchemaName("dbo")
   .withProcedureName("calculate_avail_cash_balance");


Q. How do you configure the  jdbcTemplate?
A.

<?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:batch="http://www.springframework.org/schema/batch" xmlns:p="http://www.springframework.org/schema/p" 
 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.5.xsd
  http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.0.xsd
  http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
  
 <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource">
  <property name="driverClassName" value="com.sybase.jdbc3.jdbc.SybDriver" />
  <property name="url" value="jdbc:sybase:Tds:server:7777/mydb" />
  <property name="username" value="test" />
  <property name="password" value="test" />
 </bean>
 
 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" lazy-init="true">
  <property name="dataSource" ref="myDataSource" />
 </bean>
 
 <bean id="myJdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
  <property name="dataSource" ref="myDataSource" />
 </bean>   
  
</beans>

If you have return values from stored proc that has to be recursively processed then look at
Spring JDBC Template examples -- calling stored proc, simple select, and insert with returning the generated key

Labels:

Dec 3, 2013

Pros and cons of agile development methodology and agile principles

Agile Development Interview Questions and Answers

Agile Development methodology Q1 - Q6 Agile Development methodology Q7 - Q16 Agile methodology: theme, epic and user story Pros and cons of agile development methodology and principles

Q. What are the key benefits of agile mehodology?
A.
  • Decreased time to market as agile process is based on the philosophy of early and regular releases. The iterative nature of agile development means features are delivered incrementally, enabling some benefits to be realised early as the product continues to develop.
  • Better quality as testing is integrated throughout the sprints, enabling regular inspection of the working product as it develops. This allows the product owner to make adjustments if necessary and gives the product team early sight of any quality issues. 
  • Improved communications due to active involvement and colocated multi-disciplinary teams. This provides excellent visibility for key stakeholders, both of the project’s progress and of the product itself, which in turn helps to ensure that expectations are effectively managed. 
  • Lower costs because unlike in traditional development projects, where you write a big spec up-front and then tell business owners how expensive it is to change anything, particularly as the project goes on. In fear of scope creep and a never-ending project, we resist changes and put people through a change control committee to keep them to the bare minimum. Agile development principles are different. In agile development, change is accepted. Instead of rejecting changes, the timescale is fixed and requirements progressively emerge and evolve as the product is developed.

Q. It looks too good, now what are the drawbacks of agile?
A.
  • Agile is a very sophisticated process and requires full management commitment and requires experienced and dedicated teams to achieve things within the allocated sprints. Otherwise, everything will blow up to become a backlogs. 
  • Time boxing can encourgage agile members to cut corners in terms of unit test coverage, documentation, code quality, design , failing to test negative scenarios, etc. It can also lead to over worked staff who lose motivation.
  • It assumes that all developers are created equal. Doing a particular task  might be a 5 point task for developer A, whereas  for developer B, it takes 20 points. For example, this can happen if developer B is a back-end developer and not experienced with GUI development.
  • Not all projects nor all phases are good candidate for agile. You should use agile if you can deliver  tangible releases that can be tested by the testers within the sprint. For example, a GUI screen. Some projects may spend months developing back-end architecture without any tangible deliveries. Website development is a good candidate for agile development. It is also not suited where different teams use different methodologies. What happens when a development and QA team adheres to the principles of Agile, but the platform and production support do not? 
So, there are pros and cons and some organizations make use of the hybrid approach to get the best of both worlds. Agile is commonly believed to be a set a practices, processes and tools, when in fact, Agile is really more of a mind-set and culture.



Q. What are the agile resource Management principles?
A. The resourcing principles can be abbreviated to FASTEST as shown below.



Agile projects require require experienced developers and testers to get things done in allocated sprints. More and more organizations are getting into agile methodology, and it is really worth learning and experiencing it. I was fortunate enough to work on a number of such projects. These projects do need full commitment and support of the senior management.