Locking in Hibernate using Java

In Hibernate, locking strategy can be either optimistic or pessimistic. Let’s first see the definition.

Optimistic
Optimistic locking assumes that multiple transactions can complete without affecting each other, and that therefore transactions can proceed without locking the data resources that they affect. Before committing, each transaction verifies that no other transaction has modified its data. If the check reveals conflicting modifications, the committing transaction rolls back.

Pessimistic
Pessimistic locking assumes that concurrent transactions will conflict with each other, and requires resources to be locked after they are read and only unlocked after the application has finished using the data.
Hibernate provides mechanisms for implementing both types of locking in your applications. Let’s understand in detail :

Optimistic

When your application uses long transactions or conversations that span several database transactions, you can store versioning data so that if the same entity is updated by two conversations, the last to commit changes is informed of the conflict, and does not override the other conversation’s work. This approach guarantees some isolation, but scales well and works particularly well in read-often-write-sometimes situations.

Hibernate provides two different mechanisms for storing versioning information, a dedicated version number or a timestamp.

A version or timestamp property can never be null for a detached instance. Hibernate detects any instance with a null version or timestamp as transient, regardless of other unsaved-value strategies that you specify. Declaring a nullable version or timestamp property is an easy way to avoid problems with transitive reattachment in Hibernate, especially useful if you use assigned identifiers or composite keys.

Dedicated version number

The version number mechanism for optimistic locking is provided through a @Version annotation.

Example : The @Version annotation

@Entity
public class Flight implements Serializable {
...
    @Version
    @Column(name="OPTLOCK")
    public Integer getVersion() { ... }
}

Here, the version property is mapped to the OPTLOCK column, and the entity manager uses it to detect conflicting updates, and prevent the loss of updates that would be overwritten by a last-commit-wins strategy.

The version column can be any kind of type, as long as you define and implement the appropriate UserVersionType.

Your application is forbidden from altering the version number set by Hibernate. To artificially increase the version number, see the documentation for properties LockModeType.OPTIMISTIC_FORCE_INCREMENT or LockModeType.PESSIMISTIC_FORCE_INCREMENT check in the Hibernate Entity Manager reference documentation.

Database-generated version numbers
If the version number is generated by the database, such as a trigger, use the annotation @org.hibernate.annotations.Generated(GenerationTime.ALWAYS).

Example: Declaring a version property in hbm.xml

<version
        column="version_column"
        name="propertyName"
        type="typename"
        access="field|property|ClassName"
        unsaved-value="null|negative|undefined"
        generated="never|always"
        insert="true|false"
        node="element-name|@attribute-name|element/@attribute|."
/>
columnThe name of the column holding the version number. Optional, defaults to the property name.
nameThe name of a property of the persistent class.
typeThe type of the version number. Optional, defaults to integer.
accessHibernate’s strategy for accessing the property value. Optional, defaults to property.
unsaved-valueIndicates that an instance is newly instantiated and thus unsaved. This distinguishes it from detached instances that were saved or loaded in a previous session. The default value, undefined, indicates that the identifier property value should be used. Optional.
generatedIndicates that the version property value is generated by the database. Optional, defaults to never.
insertWhether or not to include the version column in SQL insert statements. Defaults to true, but you can set it to false if the database column is defined with a default value of 0.
Timestamp

Timestamps are a less reliable way of optimistic locking than version numbers, but can be used by applications for other purposes as well. Timestamping is automatically used if you the @Version annotation on a Date or Calendar.

Example: Using timestamps for optimistic locking

@Entity
public class Flight implements Serializable {
...
    @Version
    public Date getLastUpdate() { ... }
}

Hibernate can retrieve the timestamp value from the database or the JVM, by reading the value you specify for the @org.hibernate.annotations.Source annotation. The value can be either org.hibernate.annotations.SourceType.DB or org.hibernate.annotations.SourceType.VM. The default behavior is to use the database, and is also used if you don’t specify the annotation at all.

The timestamp can also be generated by the database instead of Hibernate, if you use the @org.hibernate.annotations.Generated(GenerationTime.ALWAYS) annotation.

Example 5.4. The timestamp element in hbm.xml

<timestamp
        column="timestamp_column"
        name="propertyName"
        access="field|property|ClassName"
        unsaved-value="null|undefined"
        source="vm|db"
        generated="never|always"
        node="element-name|@attribute-name|element/@attribute|."
/>
columnThe name of the column which holds the timestamp. Optional, defaults to the property namel
nameThe name of a JavaBeans style property of Java type Date or Timestamp of the persistent class.
accessThe strategy Hibernate uses to access the property value. Optional, defaults to property.
unsaved-valueA version property which indicates than instance is newly instantiated, and unsaved. This distinguishes it from detached instances that were saved or loaded in a previous session. The default value of undefined indicates that Hibernate uses the identifier property value.
sourceWhether Hibernate retrieves the timestamp from the database or the current JVM. Database-based timestamps incur an overhead because Hibernate needs to query the database each time to determine the incremental next value. However, database-derived timestamps are safer to use in a clustered environment. Not all database dialects are known to support the retrieval of the database’s current timestamp. Others may also be unsafe for locking, because of lack of precision.
generatedWhether the timestamp property value is generated by the database. Optional, defaults to never.
Versionless optimistic locking

Although the default @Version property optimistic locking mechanism is sufficient in many situations, sometimes, you need rely on the actual database row column values to prevent lost updates.

Hibernate supports a form of optimistic locking that does not require a dedicated “version attribute”. This is also useful for use with modeling legacy schemas.

The idea is that you can get Hibernate to perform “version checks” using either all of the entity’s attributes, or just the attributes that have changed. This is achieved through the use of the @OptimisticLocking annotation which defines a single attribute of type org.hibernate.annotations.OptimisticLockType .

There are 4 available OptimisticLockTypes:

NONE
optimistic locking is disabled even if there is a @Version annotation present

VERSION (the default)
performs optimistic locking based on a @Version as described above

ALL
performs optimistic locking based on all fields as part of an expanded WHERE clause restriction for the UPDATE/DELETE SQL statements

DIRTY
performs optimistic locking based on dirty fields as part of an expanded WHERE clause restriction for the UPDATE/DELETE SQL statements

Example: OptimisticLockType.ALL mapping example

@Entity(name = "Person")
@OptimisticLocking(type = OptimisticLockType.ALL)
@DynamicUpdate
public static class Person {

    @Id
    private Long id;

    @Column(name = "`name`")
    private String name;

    private String country;

    private String city;

    @Column(name = "created_on")
    private Timestamp createdOn;

    . . .
}

Pessimistic

Typically, you only need to specify an isolation level for the JDBC connections and let the database handle locking issues. If you do need to obtain exclusive pessimistic locks or re-obtain locks at the start of a new transaction, Hibernate gives you the tools you need.

Hibernate always uses the locking mechanism of the database, and never lock objects in memory.

The LockMode class

The LockMode class defines the different lock levels that Hibernate can acquire.

LockMode.WRITEacquired automatically when Hibernate updates or inserts a row.
LockMode.UPGRADEacquired upon explicit user request using SELECT ... FOR UPDATE on databases which support that syntax.
LockMode.UPGRADE_NOWAITacquired upon explicit user request using a SELECT ... FOR UPDATE NOWAIT in Oracle.
LockMode.READacquired automatically when Hibernate reads data under Repeatable Read or Serializable isolation level. It can be re-acquired by explicit user request.
LockMode.NONEThe absence of a lock. All objects switch to this lock mode at the end of a Transaction. Objects associated with the session via a call to update() or saveOrUpdate() also start out in this lock mode.

The explicit user request mentioned above occurs as a consequence of any of the following actions:

  • A call to Session.load(), specifying a LockMode.
  • A call to Session.lock().
  • A call to Query.setLockMode().

If you call Session.load() with option UPGRADE or UPGRADE_NOWAIT, and the requested object is not already loaded by the session, the object is loaded using SELECT ... FOR UPDATE. If you call load() for an object that is already loaded with a less restrictive lock than the one you request, Hibernate calls lock() for that object.

Session.lock() performs a version number check if the specified lock mode is READUPGRADE, or UPGRADE_NOWAIT. In the case of UPGRADE or UPGRADE_NOWAITSELECT ... FOR UPDATE syntax is used.

If the requested lock mode is not supported by the database, Hibernate uses an appropriate alternate mode instead of throwing an exception. This ensures that applications are portable.

I hope you have enjoyed this post and it helped you to understand the locking mechanism in hibernate using Java. Please like and share and feel free to comment if you have any suggestions or feedback.

Tagged : / /

Make your own Java Annotations

What’s the use of Annotations?

The first question that comes into our mind is what’s the use case of annotations and why it is consider as a powerful part of Java. Annotations have a number of uses, among them:

  • Information for the compiler — There are three built-in annotations available in Java (@Deprecated@Override & @SuppressWarnings) that can be used for giving certain instructions to the compiler. For example, the @Override annotation is used for instructing compiler that the annotated method is overriding the method.

 @FunctionalInterface annotation, introduced in Java SE 8, indicates that the type declaration is intended to be a functional interface, as defined by the Java Language Specification.

  • Compile-time and deployment-time processing — Software tools can process annotation information to generate code, XML files, and so forth.
  • Runtime processing — We can define annotations to be available at runtime which we can access using java reflection and can be used to give instructions to the program at runtime.

Creating Custom Annotations

  • Annotations are created by using @interface, followed by annotation name as shown in the below example.
  • An annotation can have elements as well. They look like methods. For example in the below code, we have six elements. We should not provide implementation for these elements.
  • All annotations extends java.lang.annotation.Annotation interface. Annotations cannot include any extends clause.
@interface ClassInfo {
   String author();
   String date();
   int currentRevision() default 1;
   String lastModified() default "N/A";
   String lastModifiedBy() default "N/A";
   // Note use of array
   String[] reviewers();
}

Note: All the elements that have default values set while creating annotations can be skipped while using annotation and we can also have array elements in an annotation. For example if I’m applying the above annotation to a class then I would do it like this:

@ClassInfo(
    author="TheCodersStop",
    date = "05-10-2020"
    reviewers={"Me", "You"}
)
public class AnyClass {

}

As you can see, we have not given any value to the currentRevision , lastModified and lastModifiedBy elements as it is optional to set the values of these elements (default values already been set in Annotation definition, but if you want you can assign new value while using annotation just the same way as we did for other elements). However we have to provide the values of other elements (the elements that do not have default values set) while using annotation.

Annotations That Apply to Other Annotations

Annotations that apply to other annotations are called meta-annotations. There are several meta-annotation types defined in java.lang.annotation.

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
@Documented
@Target(ElementType.METHOD)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface StudentAnnotation{
    int studentAge() default 15;
    String studentName();
    String studentAddress();
    String studentStream() default "PCM";
}

In the above custom annotation example we have used these four annotations :  @Documented,  @Target,  @Inherited &  @Retention. Lets discuss them one by one.

@Documented

@Documented annotation indicates that whenever the specified annotation is used those elements should be documented using the Javadoc tool. (By default, annotations are not included in Javadoc.) For more information, see the Javadoc tools page.

@StudentAnnotation
public class AnyClass { 
     //Class body
}

So while generating the javadoc for class AnyClass, the annotation @MyCustomAnnotation would be included in that.

@Target

@Target annotation marks another annotation to restrict what kind of Java elements the annotation can be applied to. In our case, we have defined the target type as METHOD which means the below annotation can only be used on methods.

public class AnyClass {
   @StudentAnnotation
   public void anyMethod()
   {
       //Doing something
   }
}

If you do not define any Target type that means annotation can be applied to any element. A target annotation specifies one of the following element types as its value:

  • ElementType.ANNOTATION_TYPE can be applied to an annotation type.
  • ElementType.CONSTRUCTOR can be applied to a constructor.
  • ElementType.FIELD can be applied to a field or property.
  • ElementType.LOCAL_VARIABLE can be applied to a local variable.
  • ElementType.METHOD can be applied to a method-level annotation.
  • ElementType.PACKAGE can be applied to a package declaration.
  • ElementType.PARAMETER can be applied to the parameters of a method.
  • ElementType.TYPE can be applied to any element of a class.
@Inherited

The @Inherited annotation indicates that a custom annotation used in a class should be inherited by all of its sub classes. This is not true by default.

@StudentAnnotation
public class AnyParentClass { 
  ... 
}
public class AnyChildClass extends AnyParentClass { 
   ... 
}

Here the class AnyParentClass is using annotation @StudentAnnotation which is marked with @inherited annotation. It means that the sub class AnyChildClass inherits the @AnyCustomAnnotation.

@Retention

@Retention annotation specifies how the marked annotation is stored:

  • RetentionPolicy.SOURCE – The marked annotation is retained only in the source level and is ignored by the compiler.
  • RetentionPolicy.CLASS – The marked annotation is retained by the compiler at compile time, but is ignored by the Java Virtual Machine (JVM).
  • RetentionPolicy.RUNTIME – The marked annotation is retained by the JVM so it can be used by the runtime environment.
@Repeatable

 @Repeatable annotation, introduced in Java SE 8, indicates that the marked annotation can be applied more than once to the same declaration or type use. For more information, see Repeating Annotations.

I hope you have enjoyed this post and it helped you to create a custom Java annotation. Please like and share and feel free to comment if you have any suggestions or feedback.

Tagged : / /

Mockito doesn’t give a Hangover – Java Unit Tests

The following blog is based on an understanding of unit testing with the JUnit framework. In case your are not familiar with JUnit please check the following JUnit article.
Mockito doesn’t give you hangover because the tests are very readable and they produce clean verification errors. We will cover some basic Mockito annotations that are mostly used by the developers.

How do I drink it?

To add mockito into the project, we can add the desired mockito version by any means i.e. maven, gradle or jar file.

pom.xml
<dependency>
	<groupId> org.mockito </groupId>
	<artifactId> mockito-core </artifactId>
	<version> 2.+ </version>
	<scope> test </scope>
</dependency>
build.gradle
testCompile group: 'org.mockito', name: 'mockito-core', version: '2.23.4'
Verify interactions
import static org.mockito.Mockito.*;

// mock creation
List mockedList = mock(List.class);

// using mock object - it does not throw any "unexpected interaction" exception
mockedList.add("one");
mockedList.clear();

// selective, explicit, highly readable verification
verify(mockedList).add("one");
verify(mockedList).clear();
Stub method calls
// you can mock concrete classes, not only interfaces
LinkedList mockedList = mock(LinkedList.class);

// stubbing appears before the actual execution
when(mockedList.get(0)).thenReturn("first");

// the following prints "first"
System.out.println(mockedList.get(0));

// the following prints "null" because get(999) was not stubbed
System.out.println(mockedList.get(999));

Mockito Annotations

Before we go further, let’s explore different ways to enable the use of annotations with Mockito tests.
The first option we have is to annotate the JUnit test with a MockitoJUnitRunner as in the following example:

@RunWith(MockitoJUnitRunner.class)
public class MockitoAnnotationTest {
…
}

Alternatively, we can enable Mockito annotations programmatically as well, by invoking MockitoAnnotations.initMocks():

@Before
public void init() {
MockitoAnnotations.initMocks(this);
}

Lastly, we can use a MockitoJUnit.rule() as shown below:

public class MockitoInitWithMockitoJUnitRuleUnitTest {
 
    @Rule
    public MockitoRule initRule = MockitoJUnit.rule();
 
    ...
}

In this case, we must remember to make our rule public.

In our example, we are going to use the following annotations:-

  • @Mock – The @Mock annotation is used to create and inject mocked instances. We do not create real objects, rather ask mockito to create a mock for the class.
  • @InjectMocks – In mockito, we need to create the object of class to be tested and than insert it’s dependencies (mocked) to completely test the behavior. To do this, we use @InjectMocks annotation.

So, Let’s first create an interface called CalculatorService to provide mathematical functions.

CalculatorService.java
public interface CalculatorService {
   public double add(double input1, double input2);
   public double multiply(double input1, double input2);
}

Then, create a Java class to represent MathApplication.

MathApplication.java
public class MathApplication {
   private CalculatorService calcService;

   public void setCalculatorService(CalculatorService calcService){
      this.calcService = calcService;
   }

   public double add(double input1, double input2){
      return calcService.add(input1, input2);
   }

   public double multiply(double input1, double input2){
      return calcService.multiply(input1, input2);
   }
}

Let’s test the MathApplication class, by injecting in it a mock of calculatorService. Mock will be created by Mockito.

MathApplicationTest.java
import static org.mockito.Mockito.when;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

//RunWith attaches a runner with the test class to initialize the test data
@RunWith(MockitoJUnitRunner.class)
public class MathApplicationTest {
	
   //InjectMocks annotation is used to create and inject the mock object
   @InjectMocks 
   MathApplication mathApplication = new MathApplication();

   //Mock annotation is used to create the mock object to be injected
   @Mock
   CalculatorService calcService;

   @Test
   public void testAdd(){
      //add the behavior of calc service to add two numbers
      when(calcService.add(20.0,40.0)).thenReturn(60.0);
		
      //test the add functionality
      Assert.assertEquals(mathApplication.add(20.0, 40.0),60.0);
   }
}

 The test is successfully run using Mockito annotations.

The @Mock annotation is alternative to Mockito.mock(classToMock). They both achieve the same result. Using @Mock is usually considered “cleaner“, as we don’t fill up the tests with boilerplate assignments that all look the same.The other widely used are mentioned below:

  • @Spy – The @Spy annotation is used to create a real object and spy on that real object. A spy helps to call all the normal methods of the object while still tracking every interaction, just as we would with a mock.
  • @Captor – The @Captor annotation is used to create an ArgumentCaptor instance which is used to capture method argument values for further assertions.

I hope you have enjoyed this post and it helped you to understand the basics of mockito framework for unit testing in Java. Please like and share and feel free to comment if you have any suggestions or feedback.

Tagged : / /

JUnit Annotations with Example

Introduction

Annotations were introduced in Junit4, which makes Java code more readable and simple. This is the big difference between Junit3 and Junit4 that Junit4 is annotation based.

JUnit5 is the next generation of JUnit. The goal is to create an up-to-date foundation for developer-side testing on the JVM. This includes focusing on Java 8 and above, as well as enabling many different styles of testing.With the knowledge of annotations in JUnit5, one can easily learn and implement a JUnit test.

JUnit offers integration with CI/CD tools such as Jenkins, Teamcity etc. to help you create a sturdy delivery pipeline.

Basic Java Annotations

So here are some basic JUnit annotation that are mostly used and required for unit testing :

  • @Test – This is the test method to run, public void
  • @BeforeClass – This annotation is used if you want to execute some statements before all the test cases for e.g. test connection must be executed before all the test cases., public static void
  • @AfterClass – This annotation can be used if you want to execute some statements after all test cases for e.g. Releasing resources after executing all test case, public static void
  • @Before – This annotation is used if you want to execute some statement such as preconditions before each test case, public void
  • @After – This annotation can be used if you want to execute some statements after each Test Case for e.g resetting variables, deleting temporary files ,variables, etc, public void

A simple example will help us to understand the working of JUnit annotations.

Java Class to be tested

We are going to use a simple example regarding Account balance where we want to perform our unit testing.

package com.thecodersstop.junit;
 
public class Account {
    private double bal;
 
    public Account(double bal) {
        this.bal = bal;
    }
 
    public double getBal() {
        return bal;
    }
 
    public void setBal(double bal) {
        this.bal = bal;
    }
 
    public void withdraw(double withdrawAmount) {
        this.bal = bal - withdrawAmount;
    }
 
    public void deposit(double depositAmount) {
        this.bal = bal + depositAmount;
    }
}

Junit Test Cases

Here we have our test cases for the Account java class. This test class includes all the basic annotations mentioned above.

package com.thecodersstop.junit;

import org.junit.*;
 
public class AccountTest extends Assert {
    private Account account;
    private static double bal;
 
    @BeforeClass
    public static void BeforeClass() {
		// Code executed before the first test method
        bal = 100;
        System.out.println("Before Class");
    }
 
    @Before
    public void beforeTest() throws Exception {
		// Code executed before each test
        account = new Account(bal);
    }
 
    @Test
    public void testCase1() {
        Assert.assertEquals("Test balance", account.getBal(), bal, 0);
        System.out.println("Test balance. Balance: " + account.getBal());
    }
 
    @Test
    public void testCase2() {
        account.deposit(10);
        Assert.assertEquals("Test deposit", account.getBal(), bal, 10);
        System.out.println("Test deposit. Balance: " + account.getBal());
    }
 
    @Test
    public void testCase3() {
        account.withdraw(30);
        Assert.assertEquals("Test withdraw", account.getBal(), bal, 30);
        System.out.println("Test withdraw. Balance: " + account.getBal());
    }
 
    @After
    public void afterTest() throws Exception {
		// Code executed after each test
        account = null;
        System.out.println("refresh");
    }
 
    @AfterClass
    public static void AfterClass() {
		// Code executed after the last test method
        balance = 0;
        System.out.println("After Class");
    }
}

Run the JUnit Test Cases

Here is the output of our test cases. As we can see, the sequence of the executed test methods, complies with what we described in the starting. This JUnit test is fully passed.

Before Class
Test balance. Balance: 100.0
refresh
Test deposit. Balance: 110.0
refresh
Test withdraw. Balance: 70.0
refresh
After Class

JUnit offers integrations with IDEs such as Eclipse, IntelliJ etc. so you could test run your code quickly and easily.

Execution Sequence of JUnit Annotations

Here is a basic process flowchart of JUnit annotations that will help you to understand the flow, step by step.

@Ignores – This annotation can be used if you want to ignore some statements during test execution for e.g. disabling some test cases during test execution.

I hope you have enjoyed this post and it helped you to understand the basics of JUnit annotations. Please like and share and feel free to comment if you have any suggestions or feedback.

Tagged : / /

Java Beans and POJOs are not same

POJO classes and Beans both are used to define java objects to increase their re-usability and readability. POJOs do not have other restrictions while beans are special POJOs with some restrictions. So let’s first discuss about POJO classes and then try to apply some restrictions on them to achieve Beans.

POJO

POJO refers to the Plain Old Java Object. It is an ordinary Java object, not bound by any special restriction other than those forced by the Java Language Specification.They are simple to put in writing and perceive. They were introduced in EJB 3.0 by Sun Microsystems.

In Hibernate, POJO classes are used to store data and retrieve data.

Example of POJO Class.
public class Employee {
   String name;
   public String id;
   private double salary;
   public Employee(String name, String id,double salary) {
      this.name = name;
      this.id = id;
      this.salary = salary;
   }
   public String getName() {
      return name;
   }
   public String getId() {
      return id;
   }
   public Double getSalary() {
      return salary;
   }
}

The above example is a well-defined example of POJO class. As you can see, there is no restriction on access-modifier of fields. They can be private, default, protected or the public. It is also not necessary to include any constructor in it.

JavaBeans

A JavaBean is still a POJO but introduces a strict set of rules around how we implement it:

  • Access levels – properties are private and we expose getters and setters
  • Method names – getters and setters follow the getX and setX convention (in the case of a boolean, isX can be used for a getter)
  • Default Constructor – a no-argument constructor must be present so an instance can be created without providing arguments, for example during deserialization
  • Serializable – implementing the Serializable interface allows us to store the state
Example of Java Bean Class.
public class EmployeeBean implements Serializable {
 
    private static final long serialVersionUID = -3761445487636086334L;
    private String name;
    private LocalDate startDate;
 
    public EmployeeBean() {
    }
    public EmployeeBean(String name, LocalDate startDate) {
        this.name = name;
        this.startDate = startDate;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    //  additional getters/setters
}

Due to this it is stated that all JavaBeans are POJOs but not all POJOs are JavaBeans.

I hope you have enjoyed this post and it helped you to understand the difference between JavaBeans and POJO classes. Please like and share and feel free to comment if you have any suggestions or feedback.

Tagged :
%d bloggers like this: