Tuesday, April 25, 2017

JPA EntityListner example with Spring Boot 1.5.1

To audit any transaction table you can use EntityListener Annotation of the JPA. JPA provide the EntityListener annotations that attach a listener class with the entity that you want to audit. 

What is audit table ? 

Audit Tables are used to track transactions against a particular table or tables. They allow you to see an ongoing "log" for future use.  

There may be users and/or applications that have access to insert, update, and delete out of that table. If you may want to have a quick and easy way to track who is doing what on that table. 

Scope -  
We will create a trigger like functionality. We shall audit all the DML operations (i.e. Insert, update and delete) on a table. We shall log all details of the operation, time-stamp, and the user name details in the audit log table. 

Dependencies -  

Create Application -

First create User Entity class that contain the user details data.

User.java

Create Spring data repository to create CRUD operations on the database.

UserRepository.java

Create a Controller class to handle the Request -

UserController.java

Create Application class for spring boot configuration.

Application.java


Project Structure -
























Compile the application with below maven command -

mvn clean install  

Run the example by below command on the command line  - 

mvn spring-boot:run 

You can now perform create and update operation on the user entity.

Create AuditLog Entity and AuditLogRepository class -

Create a AuditLog entity for audit log table, to keep the audit data -

AuditLog.java


Create a Spring repository for CRUD operation on the on database.


AuditLogRepository.java

Attach AuditLog entity with User Entity class -

First create a Entity Listener class that will listen the User table, and if any update operation performed on the User entity, the listener will call the call back methods.

UserAuditLogListener.java

The same callback method or entity listener method can be annotated with more than one callback annotation. For a given entity, you cannot have two methods being annotated by the same callback annotation whether it is a callback method or an entity listener method. A callback method is a no-arg method with no return type and any arbitrary name. An entity listener has the signature void <METHOD>(Object) where Object is of the actual entity type (note that Hibernate Entity Manager relaxed this constraint and allows Object of java.lang.Object type (allowing sharing of listeners across several entities.) 

A callback method can raise a RuntimeException. The current transaction, if any, must be rolled back.

The following callbacks can be used -

Type
Description
@PrePersist 
Executed before the entity manager persist operation is actually executed or cascaded. This call is synchronous with the persist operation. 
@PreRemove 
Executed before the entity manager remove operation is actually executed or cascaded. This call is synchronous with the remove operation. 
@PostPersist 
Executed after the entity manager persist operation is actually executed or cascaded. This call is invoked after the database INSERT is executed. 
@PostRemove 
Executed after the entity manager remove operation is actually executed or cascaded. This call is synchronous with the remove operation. 
@PreUpdate 
Executed before the database UPDATE operation. 
@PostUpdate 
Executed after the database UPDATE operation. 
@PostLoad 
Executed after an entity has been loaded into the current persistence context or an entity has been refreshed. 

For more information please refer this link.

Thing to keep in mind!!
You can define several entity listeners per entity at different level of the hierarchy. You can also define several callbacks at different level of the hierarchy. But you cannot define two listeners for the same event in the same entity or the same entity listener.

When an event is raised, the listeners are executed in this order: 
@EntityListeners for a given entity or super class in the array order 
Entity listeners for the super classes (highest first) 
Entity Listeners for the entity 
Callbacks of the super classes (highest first) 
Callbacks of the entity

Modify User entity to attach EntityListener class -

User.java

 Annotation @EntityListners specifies the callback listener classes to be used for an entity or mapped super class.  
@EntityListeners (value = UserAuditLogListener.class) will attach the UserAuditLogListener.class with the User Entity class. 

JPA Entitylisteners are not entities, they are simply java classes in which JPA life cycle callback methods are implemented using annotations.

Save data in the AuditLog table-

To inject AuditLogRepository into the UserAuditLogListener we can use an ApplicationContextAware Bean that will give the AuditRepository from Spirng context  to save the Audit data. So, Create a BeanUtility service that implement the application context.

BeanUtility.java
Create a controller class to handle the request for audit log data .

AuditorController.java



Updated Project Structure -


Now build the program using below maven command on the command line  - 

mvn clean install  

Run the example by below command on the command line  - 

mvn spring-boot:run


You can download the sample code from below link - 
Sample Program


Wednesday, April 19, 2017

Spring boot scheduling with annotation

Spring Boot provides annotation support for task scheduling. It is easy way to develop and run a Task scheduler without using any xml and bean configurations.

Simply add the annotation @Scheduled on the task scheduler method with required interval time.

In this example, we will see how to use Spring @Scheduled annotation to schedule a task.

Enable scheduling annotations

To enable support for @Scheduled annotation add @EnableScheduling to one of your @Configuration classes:


You are free to pick and choose the relevant annotations for your application. For example, for more fine-grained control you can additionally implement the SchedulingConfigurer interfaces.

The @Scheduled annotation

The @Scheduled annotation can be added to a method along with trigger metadata. 

Important: The simple rules that need to be followed to annotate a method with @Scheduled are:
  • A method should not accept any parameters
  • A method should have void return type
For example, the following method would be invoked every 5 seconds with a fixed delay, meaning that the period will be measured from the completion time of each preceding invocation.


If a fixed rate execution is desired, simply change the property name specified within the annotation.
The following would be executed every 5 seconds measured between the successive start times of each invocation.


For fixed-delay and fixed-rate tasks, an initial delay may be specified indicating the number of milliseconds to wait before the first execution of the method.


If simple periodic scheduling is not expressive enough, then a cron expression may be provided. For example, the following will only execute on weekdays.

Thank you.

Saturday, September 27, 2014

Execute and Wait Interface in Struts2


The Execute and Wait Interceptor (execAndWait) is great for running long-lived actions in the background while showing the user a nice progress meter. This also prevents the HTTP request from timing out when the action takes more than 5 or 10 minutes. Click Here for more info.

Let’s see how we can use it –

1. Welcome.jsp -
This is the initial jsp which will request for some processing.

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib  uri="/struts-tags" prefix="s" %>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
        <h1>execAndWait interceptor</h1>
        <h2>
            This Web app shows how to use execAndWait Interface <br/>
            to show a page when business logic taking long time <br/>
            and you want to show another page, till the execution<br/>
            is not completed successfully.
        </h2>
        <br/>
        <br/>
        <s:form name="frm" action="waitAction.action">
            <s:submit value="Process ..."/>
        </s:form>
    </body>
</html>



2. Wait.jsp
The page which will shows when user is waiting for server response.

<%@ taglib prefix="s" uri="/struts-tags" %>
<head>
<head>
    <meta http-equiv="refresh" content="2;"/>
    <title>Please Wait ...</title>
</head>
<body>
    <div style="width:200px">
        Please wait...
    </div>
</body>
</html>



3. Done.jsp
This is the jsp will be displayed after processing

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Thanks for waiting ...</title>
    </head>
    <body>
        <h1>Process completed!!!</h1>
        <h2>Thanks for waiting!! </h2>
    </body>
</html>
</html>

4. Action Class:

This Action is called from the welcome.jsp file. It will process the actual business logic. Name it as “WaitAction.java”
package action;

import com.opensymphony.xwork2.ActionSupport;

public class WaitAction extends ActionSupport {
    /* default constructor */

    public WaitAction() {
    }

    @Override
    public String execute() {
        try {
            /* wait for 12000 ms */
            Thread.sleep(12000);
        } catch (Exception e) {
            System.out.println(e);
        }
        return SUCCESS;
    }
} // end of class



5. Make an entry in struts.xml file for action class –

This interceptor is already configured but is not part of any of the default stacks. Because of the nature of this interceptor, it must be the last interceptor in the stack. 

Important: Because the action will be running in a separate thread, you can't use ActionContext because it is a ThreadLocal. This means if you need to access, for example, session data, you need to implement SessionAware rather than calling ActionContext.getSession(). 

Parameters for execAndWait Interceptor: 

threadPriority (optional) - the priority to assign the thread. Default is Thread.NORM_PRIORITY. 

delay (optional) - an initial delay in millis to wait before the wait page is shown (returning wait as result code). Default is no initial delay. 

delaySleepInterval (optional) - only used with delay. Used for waking up at certain intervals to check if the background process is already done. Default is 100 millis. 

<package name="default" extends="struts-default">
    <action name="waitAction" class="action.WaitAction">
        <interceptor-ref name="defaultStack"/>
        <interceptor-ref name="execAndWait">
            <param name="delay">1500</param>
        </interceptor-ref>
        <result name="wait">/jsp/Wait.jsp</result>
        <result name="success">/jsp/Done.jsp</result>
    </action>
</package>


6. Entry in web.xml file –

<filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
    <welcome-file>jsp/welcome.jsp</welcome-file>
</welcome-file-list>

This would be folder structure of your project, after developing all the necessary files



Now deploy and run the webapp.

Welcome.jsp



Wait .jsp


Done.jsp


Thanks for reading ....Namaste ....

How to write a Simple Spring Program ?


This is one of the simplest program, which uses DI (Dependency Injection) feature of Spring.
For this tutorial you need Spring_2.5.jar and commons-logging-1.1.1.jar file.

I am using NetBeans 7.2 for this tutorial..

Lets Start -

1. Create a class with main function, in my example i am creating class FirstSpringProgram.java containing main class.

FirstSpringProgram.java

/**
 *
 * @author Vikas Kumar Verma
 */
public class FirstSpringProgram {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {

        System.out.println("JSR");
        /**
         * Create and dispense bean, It load Bean Definition and wire bean
         * together.
         */
        ApplicationContext applicationContext
                = new FileSystemXmlApplicationContext(
                        "E:\\vikas\\rnd\\FirstSpringProgram\\Spring.xml");
        /**
         * Get Bean using Bean ID declred in Spring.xml file.
         */
        SpringBean springBean = (SpringBean) applicationContext.getBean("SpringBean");
        /**
         * Executing the bean method.
         */
        System.out.println("Out put from Spring Bean: " + springBean.callSpring());
        System.out.println("Thanks");

    }
} /* End of class */



2. Now we need to create Interface which represent the Spring Bean, Name this file as

SpringBean.java - 

/*
 * Interface declaring prototype of Spring Bean
 */
package firstspringprogram.bean;

/**
 *
 * @author Vikas Kumar Verma
 */
public interface SpringBean {

    /**
     * Bean Method return bean message.
     *
     * @return String
     */
    public String callSpring();
}
/* End of class */



3. Create a Bean class implimenting SpringBean Interface, as SpringBeanImpl.java

SpringBeanImpl.java -

package firstspringprogram.bean;

/**
 * @author : Vikas Kumar Verma
 */
public class SpringBeanImpl implements SpringBean {

    /**
     * Bean Method return bean message.
     *     
* @return String
     */
    @Override
    public String callSpring() {
        /**
         * Return Bean Message
         */
        return "Thank You for Calling Me ... ";
    }
}
/* End of class */



4. Now we have to map the bean with spring container, to do this
you need to create and xml config file which register the bean(interface)
with its implimentation.

Spring.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

    <bean id="SpringBean" class="firstspringprogram.bean.SpringBeanImpl">
    </bean>
</beans>


Now you have done with it, just compile the program.
The output should be like this -

Output from Spring Bean:

Thank You for Calling Me …

Thanks

Monday, September 22, 2014

How to set max length of a TextField in fxml ?

Sometime it required to set max length of a TextField, but unfortunately, fxml does not provide this functionality.

So how to do this ?
To set the max length, there are two ways.

1. Create a Change Listener class and register it , with TextField Object, for which you want to set max length.

2. Create a concrete class, and extend it with TextField class.

Here we are going to see how to implement first options that is -
1. Create a Change Listener class and register it , with TextField Object, for which you want to set max length.

Change Listener -

Implement ChangeListner and add it to the TextField, for which you want to set max character length.

To do that, create a concrete class, and implement it with javafx.beans.value.ChangeListener

This listener notice whenever state of text field (its observable) is changed (Here in this case a text field).

public class ChangeListener implements javafx.beans.value.ChangeListener<String>

Interface ChangeListener, have a method changed; this method is called whenever stated of observable text field is changed.


public void changed(ObservableValue<? extends String> observableValuem, String oldValue, String newValue)


In above method signature, parameter oldValue contains the old value of text field, and newValue parameter contains the changed value (new value).


We can add our code to control the max length of TextField like this -


public void changed(ObservableValue<? extends String> observableValue
String oldValue, String newValue) {


/* To check if the value is null then return */
if (newValue == null){
return;
}


/* Check the length of new value length is less then defined max length then   set the new value to the text field, else keep old value in text field. */


if (newValue.length() > maxLength) {
TextField.setText(oldValue);
} else {
TextField.setText(newValue);
}
} // End of Method

Register listener with text field -

In 'initialize' method of controller class, add listener like this -
textField.textProperty().addListener(new ChangeListener(TextField, maxLength));


In the above code snippet, textField is the text filed in which you want to add listener, and ‘maxLength’ is max length of text field.


Example  -


fxml file -


<?xml version="1.0" encoding="UTF-8"?>


<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>


<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" 
fx:controller="com.fxml.FXMLDocumentController">
   
<children>
       <Label fx:id="label" layoutX="46.0" layoutY="51.0" minHeight="16" 
minWidth="69" text="User Name" />
      <TextField fx:id="userName" layoutX="142.0" layoutY="50.0"  
prefHeight="25.0" prefWidth="139.0" promptText="Max Size is 5 Char"   />
     <Button layoutX="106.0" layoutY="88.0" mnemonicParsing="false" text="Ok" />
   </children>
</AnchorPane>

Controller Class -
/*
* This is my controller class.
*/
package com.fxml;


import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import com.listener.ChangeListener;


/**
*
* @author vikas
*/
public class FXMLDocumentController implements Initializable {


   @FXML
   private Label label;


   @FXML
   private TextField userName;


   @FXML
   private void handleButtonAction(ActionEvent event) {
   }


   @Override
   public void initialize(URL url, ResourceBundle rb) {


       /* max length of text field user name */
       int maxLength = 5;


       /* add ChangeListner to TextField */
           userName.textProperty().addListener(new ChangeListener(userName, maxLength));


   }


} // End of class

Change Listener Class -
package com.listener;
/*
This listener calass is called to set maximum length of any text field.
Example -
TextField textField;
ChangeListener listener = new ChangeListener(TextField, 5); // set max length as 5
textField.textProperty().addListener(listener);
*/


import javafx.beans.value.ObservableValue;
import javafx.scene.control.TextField;


/**
*
* @author vikas
*/
public class ChangeListener implements javafx.beans.value.ChangeListener<String> {


   private int maxLength;
   private TextField textField;


   public ChangeListener(TextField textField, int maxLength) {
       this.textField= textField;
       this.maxLength = maxLength;
   }


   public int getMaxLength() {
       return maxLength;
   }


   @Override
   public void changed(ObservableValue<? extends String> ov, String oldValue,
           String newValue) {


       if (newValue == null) {
           return;
       }


       if (newValue.length() > maxLength) {
           textField.setText(oldValue);
       } else {
           textField.setText(newValue);
       }
   }


}// End of Class


Main class -


/*
* Main class to load fxml class.
*/
package com.fxml;


import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;


/**
*
* @author vikas
*/
public class Main extends Application {


   @Override
   public void start(Stage stage) throws Exception {
       Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));


       Scene scene = new Scene(root);


       stage.setScene(scene);
       stage.show();
   }


   /**
    * @param args the command line arguments
    */
   public static void main(String[] args) {
       launch(args);
   }


} // End of Class


Output -
Input Maximum value in text field -



Thank You ...