Saturday, July 1, 2017

Pessimistic and optimistic locking in Hibernate

1. Intro


When data can be updated by different sessions, sometimes we have to make some additional checking if data are consistent.

From jboss documentation:

Locking is perhaps the most ignored persistence consideration. Most applications tend to ignore thinking about concurrency issues during development, and then smush in a locking mechanism before going into production. Considering the large percentage of software projects that fail or are canceled, or never achieve a large user base, perhaps this is logical. However, locking and concurrency is a critical or at least a very important issue for most applications, so probably should be something considered earlier in the development cycle.

Optimistic locking assumes that the data will not be modified between when you read the data until you write the data. This is the most common style of locking used and recommended in today's persistence solutions. The strategy involves checking that one or more values from the original object read are still the same when updating it. This verifies that the object has not changed by another user in between the read and the write.

Pessimistic locking means acquiring a lock on the object before you begin to edit the object, to ensure that no other users are editing the object. Pessimistic locking is typically implemented through using database row locks, such as through the SELECT ... FOR UPDATE SQL syntax. The data is read and locked, the changes are made and the transaction is committed, releasing the locks.


2. Application structure

All code related with locking is placed in TEST source set. In MAIN - just HibernateUtil and DTO files.



3. build.gradle


Here I have compile dependencies for hibernate and mysql. And test dependencies for slf4j, spock, junit.

group 'com.demien.hibernate'version '1.0-SNAPSHOT'
apply plugin: 'groovy'apply plugin: 'java'
sourceCompatibility = 1.8
repositories {
    mavenCentral()
}

dependencies {
    compile 'org.hibernate:hibernate-core:5.2.10.Final'    
    compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.6'

    testCompile group: 'junit', name: 'junit', version: '4.12'    
    testCompile group: 'org.spockframework', name: 'spock-core', version: '1.1-groovy-2.4'    
    testCompile group: 'org.slf4j', name: 'slf4j-log4j12', version: '1.7.25'
}


4. Hibernate Util

Just regular settings for MySQL connection and 3 dto files with annotations which will be  used for testing: Role, User and UserGroup.

package com.demien.hiblock.db;

import com.demien.hiblock.dto.Role;
import com.demien.hiblock.dto.User;
import com.demien.hiblock.dto.UserGroup;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;


public class HibernateUtil {

    private static SessionFactory sessionFactory;

    static {
        final Configuration configuration = new Configuration();
        configuration.addAnnotatedClass(User.class);
        configuration.addAnnotatedClass(UserGroup.class);
        configuration.addAnnotatedClass(Role.class);

        configuration.setProperty("hibernate.connection.driver_class", "com.mysql.jdbc.Driver");
        configuration.setProperty("hibernate.connection.url", "jdbc:mysql://localhost:3306/test");
        configuration.setProperty("hibernate.connection.username", "test");
        configuration.setProperty("hibernate.connection.password", "test");
        configuration.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
        configuration.setProperty("hibernate.hbm2ddl.auto", "update");
        configuration.setProperty("hibernate.show_sql", "true");

        StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
        sessionFactory = configuration.buildSessionFactory(builder.build());
    }

    public static Session getSession()
            throws HibernateException {
        return sessionFactory.openSession();
    }
}

5. Base test class

I used separate test files for locking types, so I moved common logic to BaseTest class.

package com.demien.hiblock

import com.demien.hiblock.db.HibernateUtil
import com.demien.hiblock.dto.Role
import com.demien.hiblock.dto.User
import com.demien.hiblock.dto.UserGroup
import org.hibernate.LockMode
import org.hibernate.LockOptions
import org.hibernate.resource.transaction.spi.TransactionStatus
import spock.lang.Specification

abstract class BaseTest extends Specification {
    def session = HibernateUtil.getSession()

    def setupSpec() {
        println "Starting"    }

    def cleanupSpec() {
        println "Done!"    }

    def setup() {
        doInTransaction({
            session.createQuery("delete from User").executeUpdate()
            session.createQuery("delete from UserGroup").executeUpdate()
            session.createQuery("delete from Role").executeUpdate()
        })
    }

    def cleanup() {
        session.clear()
    }

    def doInTransaction(f) {
        def tx = session.getTransaction()
        if (tx.getStatus().equals(TransactionStatus.ACTIVE)) {
            tx.commit()
        }
        tx.begin()
        f()
        tx.commit()
    }

    def doInAnotherSession(f) {
        def oldSession = session        session = HibernateUtil.getSession()
        f()
        session = oldSession
    }

    def doAsync(f) {
        def runnale = new Runnable() {
            @Override            void run() {
                f()
            }
        }
        def thread = new Thread(runnale)
        thread.start()

    }

    def createEntity(entity) {
        doInTransaction({
            session.persist(entity)
        })
    }

    def updateEntity(entity) {
        doInTransaction({
            session.merge(entity)
        })
    }

    def mergeEntity(entity) {
        doInTransaction({
            session.merge(entity)
        })
    }

    def updateEntityInAnotherSession(entity) {
        doInAnotherSession({ updateEntity(entity) })
    }

    def lockEntity(entity) {
        session.buildLockRequest(new LockOptions(LockMode.PESSIMISTIC_WRITE)).lock(entity)
    }

    def lockEntityInAnotherSession(entity) {
        doInAnotherSession({ lockEntity(entity) })
    }

    def createTestUser() {
        createEntity(new User(1l, "Huan Sebastyan"))
    }

    def loadTestUser() {
        return session.get(User.class, 1L)
    }

    def createTestGroup() {
        createEntity(new UserGroup(1L, "SYSDBA", "Database Administrators"))
    }

    def loadTestGroup() {
        return session.get(UserGroup.class, 1L)
    }

    def createTestRole() {
        createEntity(new Role(1L, "SYSDBA", "Admin role"))
    }

    def loadTestRole() {
        return session.get(Role.class, 1L)
    }

}

6. Optimistic locking

As it was mentioned before, in  optimistic locking strategy we are not locking data physically, we are just checking was data modified before our update or not. We can do that in 2 ways:

  • by version checking - if version is the same - record was not chenged
  • by all fields checking - if all fields remained the same - record was not changed


6.1 by Version

In entity class we have to annotate one field with @Version. This field will be incremented by hibernate every time we update the record.

@Entity
public class User {

    @Id    
    @Column    
    private Long userId;

    @Column    
    private String userName;

    @Version    
    private Long version;



Now let's write the test:

def "it should fail if record was changed by another session"() {
    given:
    createTestUser()
    User loadedUser1 = loadTestUser()
    User loadedUser2 = loadTestUser()
    loadedUser1.setUserName("Updated1")
    loadedUser2.setUserName("Updated2")

    when:
    updateEntityInAnotherSession(loadedUser1)
    updateEntity(loadedUser2)

    then:
    thrown OptimisticLockException

}

In output window we will find:
Hibernate: insert into User (userName, version, userId) values (Huan Sebastyan, 0, 1)
Hibernate: select user0_.userId as userId1_1_0_, user0_.userName as userName2_1_0_, user0_.version as version3_1_0_ from User user0_ where user0_.userId=1
Hibernate: update User set userName=Updated2, version=1 where userId=1 and version=0
Hibernate: update User set userName=Updated2, version=1 where userId=1 and version=0

Hibernate automatically added version fields to UPDATE and WHERE clauses. As a result, last update will fail because record was updated in another session and now it has version 1 , not 0.

6.2 by all fields checking

To entity class we have to add additional annotations:
@Entity
@DynamicUpdate
@OptimisticLocking(type = OptimisticLockType.DIRTY)
public class UserGroup {

    @Id    
    @Column    
    private Long groupId;

    @Column    
    private String groupName;

    @Column    
    private String groupDescription;



Let's write the test:
def "it should fail if record was changed by another session"() {
    given:
    createTestGroup()
    UserGroup loadedGroup1 = loadTestGroup()
    UserGroup loadedGroup2 = loadTestGroup()
    loadedGroup1.setGroupName("Updated name")
    loadedGroup2.setGroupDescription("Updated description")


    when:
    updateEntityInAnotherSession(loadedGroup1)

    updateEntity(loadedGroup2)

    then:
    thrown OptimisticLockException
}


In output we will find:
Hibernate: insert into UserGroup (groupDescription, groupName, groupId) values (Database Administrators, SYSDBA, 1)
Hibernate: select usergroup0_.groupId as groupId1_2_0_, usergroup0_.groupDescription as groupDes2_2_0_, usergroup0_.groupName as groupNam3_2_0_ from UserGroup usergroup0_ where usergroup0_.groupId=1
Hibernate: update UserGroup set groupDescription=Updated description, groupName=Updated name where groupId=1 and groupDescription=Database Administrators and groupName=SYSDBA
Hibernate: update UserGroup set groupDescription=Updated description, groupName=Updated name where groupId=1 and groupDescription=Database Administrators and groupName=SYSDBA

Hibernate automatically adds changed fields to were clause. So if field was changed by another session - it will not match were clause, records will not be updated.

7. Pessimistic locking

Pessimistic locking is applied on Database level. It "physically" locks updated record. And if other session is trying to update it - it has to wait till locking session commits changes. In MySQL for such locking used SELECT ... FOR UPDATE syntax.
In test provided below, we lock record and after that we are trying to update it in another session.
This another session will hung and after 1 minute if will fail by timeout with LockTimeout exception.


def "it should throw the exception on trying to update locked record"() {
    given:
    createTestRole()
    Role role1 = loadTestRole()

    lockEntity(role1)

    when:
    doInAnotherSession({

        Role role2 = loadTestRole()
        role2.setRoleDescription("Updated description")
        mergeEntity(role2)

    })

    then:
    thrown LockTimeoutException

}

Output:
Hibernate: insert into Role (roleDescription, roleName, roleId) values (?, ?, ?)
Hibernate: select roleId from Role where roleId =? for update
Hibernate: select role0_.roleId as roleId1_0_0_, role0_.roleDescription as roleDesc2_0_0_,
Hibernate: update Role set roleDescription=?, roleName=? where roleId=?
12:59:15,754  WARN SqlExceptionHelper:129 - SQL Error: 1205, SQLState: 41000
12:59:15,755 ERROR SqlExceptionHelper:131 - Lock wait timeout exceeded; try restarting transaction
12:59:15,756  INFO AbstractBatchImpl:193 - HHH000010: On release of batch it still contained JDBC statements
12:59:15,756 ERROR ExceptionMapperStandardImpl:39 - HHH000346: Error during managed flush [could not execute statement]


As you can see from logs, by SELECT for UPDATE record was locked. And UPDATE in another session was not update to update the record.


8. The end.

Source code can be downloaded from here.

Monday, June 5, 2017

ReactJS getting started

ReactJS official page: https://facebook.github.io/react/
From wiki:
React (sometimes styled React.js or ReactJS) is an open-source JavaScript library[2] for building user interfaces.
It is maintained by FacebookInstagram and a community of individual developers and corporations.[3][4][5] According to JavaScript analytics service Libscore, React is currently being used on the websites of NetflixImgurBufferBleacher ReportFeedlyAirbnbSeatGeekHelloSignWalmart, and others.[6]
React allows developers to create large web applications that use data which can change over time, without reloading the page. Its main goal is to be fast, simple and scalable. React processes only user interfaces in applications. This corresponds to View in the Model-View-Controller (MVC) template, and can be used in combination with other JavaScript libraries or frameworks in MVC, such as AngularJS.[7]

1. Intro 

So what is ReactJS? In shorts, it's a component-based library for building rich web UI. Main concept: UI elemnts(components) has to be built from more simple elements(components).

In this tutorial we will be building application for managing users and departments. For that we will create set of ReactJS components which will help us to create entities(Users, Departments) and show existing entities as tables. This entities (Departments and Users) are dependent, because User have to be assigned to department. So, on user creation we will have to select department from list of existing.








2. Create application 

To start working with ReactJS we have to do just a few things:

2.1. First of all we need nodeJS module create-react-app. To install it: 

$ npm install -g create-react-app

2.2. After it installation we can to create our ReactJS application by running: 

$ create-react-app my-reactjs-test-app

Output should be something like:
Creating a new React app in ......
Installing packages. This might take a couple minutes.
Installing react, react-dom, and react-scripts...
.........
Success! Created my-reactjs-test-app at ......my-reactjs-test-app
Inside that directory, you can run several commands:

  npm start
    Starts the development server.

  npm run build
    Bundles the app into static files for production.

  npm test
    Starts the test runner.

  npm run eject
    Removes this tool and copies build dependencies, configuration files
    and scripts into the app directory. If you do this, you can’t go back!

We suggest that you begin by typing:

  cd my-reactjs-test-app
  npm start

Happy hacking!


2.3. Now we can run NodeJS server by executing 2 last suggested steps: 

$  cd my-reactjs-test-app
$ npm start

Output should be: 
Compiled successfully!
You can now view my-reactjs-test-app in the browser.
  Local:            http://localhost:3000/
  On Your Network:  http://172.26.142.32:3000/
Note that the development build is not optimized.
To create a production build, use npm run build.


2.4. Open browser 

Now we can open suggested URL in browser: http://localhost:3000/
It should show something like:

3. JSX

To make this components composition process simple, ReactJS provide new syntax: JSX - it's a combination HTML tags with Javscript:
class SimpleComponent extends React.Component {
   render() {
      return (
         <div>
            <h1>{10+1}</h1>
         </div>
      );
   }
}
As you can see, HTML tags (<div> and other child tags)  are located inside Javascript function. And also this HTML block has embedded Javascript block {10+1}.

When component was created - we can use it in another components:
class ComplexComponent extends React.Component {
render() {
return (
<div>
<h1>Several simple components:</h1>
<SimpleComponent/>
<SimpleComponent/>
</div>
);
}
}

4. Components

There are 2 ways of components definition: functional-component style and class-component style.

Functional style is more simple and short. And it's good for "stateless"components: for simple components which are just UI elements without any logic related with component state:

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

or as CONST:

const renderLabelForColumn = column => (<label className="formLabel">{column.label}:</label>);


Class-style is more complex, but it has much more additional features related with component state:

class ObjectList extends Component {
    constructor(props) {
        super(props);
        this.handleObjectCreation = this.handleObjectCreation.bind(this);
    }

    handleObjectCreation(obj) {
        this.props.handleObjectCreation(obj);

    }

    render() {
        return renderObjectListForm(this.props.objectType, this.props.title, this.props.columns, this.props.objectList, this.handleObjectCreation, this.props.selectors);
    }

}

5. Properties and states

5.1 Properties

User components can have custom properties just like regular HTML components:

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

- name for "Hello" will be taken from properties:

Now we can use use this component with different values of property "name":

function App() {
  return (
    <div>
      <Welcome name="Joe" />
      <Welcome name="Huan" />
      <Welcome name="Sebastyan" />
    </div>
  );
}

Important things here:
  • properties are "read-only". For dynamic things like saving current state we have  to use states.
  • as a property we can also pass handler function from  level "above": 

const renderAddObjectForm = (objectType, columns, selectors, submitHandler) => (
    <div className="addObject">
        <form onSubmit={submitHandler}>
        </form>  
    </div>
)

5.2. States

In contrary to properties, states are needed for holding some data which can be changed. Main operations with states are:

  • we can set default value for state in constructor (in example below it's an empty array for userList property). 
  • we can change the state using setState method (function which is doing that can be pulled done by component hierarchy to lower level)
  • we can pass state object as a property to components on lower levels of hierarchy(in example below we are passing userList from state to component ObjectList as property with name  objectList)


function userCreation(user) {
    this.setState(
            prevState => {
                var list = prevState.userList;
                list.push(user);
                this.setState({userList: list});
            }
    );
}

class Body extends Component {

    constructor(props) {
        super(props);
        this.handleUserCreation = userCreation.bind(this);
        this.state = {userList: []};
    }

    render() {
        return (
                <div>
                    <ObjectList objectList={this.state.userList} handleObjectCreation={this.handleUserCreation} />
                </div>
                );
    }
}


6. Coding: components for new entity creation

Now let's start with coding. First of all let's create a directory "components" inside "src" directory. And a new JavaScript file: "AddObjectForm.js"

6.1. Lets create a helper function for extracting values from form.


function getFormValue(form, valueName) {
    var result;
    for (var i = 0; i < form.elements.length; i++) {
        if (form.elements[i].name === valueName)
            result = form.elements[i].value;
    }
    return result;
}

6.2. Component for rendering column labels.


const renderLabelForColumn = column => (<label className="formLabel">{column.label}:</label>);

6.3. Component for rendering editor field.

Here we are passing selectors object, which may contain array for displaying combobox (HTML SELECT component). If array with values is not present - we are displaying simple text field(HTML INPUT).

const renderEditorForColumn = (column, selectors) => {
    if (selectors && selectors[column.name]) {
        var list = selectors[column.name];
        let options = list.map((el) =>
            <option key={el} value={el}>{el}</option>
        );
        return (<select name={column.name}>{options}</select>);
    } else {
        return (<input name={column.name} type="text"/>);
    }
};


6.4. Component for rendering list of pairs: Field Label -> Editor

List of columns is passed by columns parameter. We are iterating this list and creating for every element of the list corresponding pair of elements: Fileld Label -> Editor.


const renderAddColumnsList = (objectType, columns, selectors) => {
    let rows = columns.map((column) =>
        <div key={objectType + "-" + column.name}> 
            {renderLabelForColumn(column)}
            {renderEditorForColumn(column, selectors)}
        </div>
    );
    return (<div>{rows}</div>);
};


6.5. Form component - container for field list

Here we creating the form with submit handler which was passed as property

const renderAddObjectForm = (objectType, columns, selectors, submitHandler) => (
    <div className="addObject">
        <form onSubmit={submitHandler}>
            <fieldset>
                <legend>Create new</legend>
                {renderAddColumnsList(objectType, columns, selectors)}
                <br/>
                <label>Press the button:</label>
                <input type="submit" values="Submit"/>
            </fieldset>
        </form>  
    </div>
)



6.6. Main class component for AddObjectForm

We are using class component, for being able to use constructor. In conctructor we can set binding for hanleSubmit function, to make it work properly in callbacks.


class AddObjectForm extends Component {

    constructor(props) {
        super(props);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleSubmit(event) {
        event.preventDefault();
        var form = event.target;
        var formObject = {};
        this.props.columns.forEach((column) => formObject[column.name] = getFormValue(form, column.name));
        this.props.onSubmit(formObject);
    }

    render() {
        return renderAddObjectForm(this.props.objectType, this.props.columns, this.props.selectors, this.handleSubmit);
    }
}


7. Coding: components for showing the list of existing objects

Let's create another file in src/components: ObjectList.js

7.1. Component for rendering one row of data in the table


const renderTableRow = (columns, data) => {
    let rowContent = columns.map((column) =>
        <td key={column.name + "-" + data.id}>{data[column.name]}</td>
    );
    return (<tr key={data.id}>{rowContent}</tr>);
};


7.2. Component for rendering all rows


const renderTableRows = (columns, objectList) => (
    objectList.map((data) => renderTableRow(columns, data))
);


7.3. Component for rendering table header


const renderTableHeader = (columns) => (
    columns.map((column) =>
        <th key={column.name}>{column.label}</th>
    )
);


7.4. Component for rendering table itself

If we have no data for table (in objectList) we are just return null.

const renderTable = (columns, objectList) => {
    if (!objectList || objectList.length === 0)
        return null;
    return(
            <div>
                <h3>List of existing:</h3>
                <table className="objectListTable">
                    <tbody>
                        <tr>
                            {renderTableHeader(columns)}
                        </tr>               
                        {renderTableRows(columns, objectList)}
                    </tbody>        
                </table>
            </div>
    );
};



7.5 Component for rendering AddObjectForm together with table of existing objects

AddObjectForm is rendered as ussual HTML component.

const renderObjectListForm = (objectType, title, columns, objectList, creationHadler, selectors) => (
    <div className="objectList">
        <h2>{title}</h2>
        <AddObjectForm onSubmit={creationHadler} columns={columns} selectors={selectors} objectType={objectType}/>
        <br/>
        {renderTable(columns, objectList)}
    </div>
);


7.6. Class component with proper hadlerBinding


class ObjectList extends Component {
    constructor(props) {
        super(props);
        this.handleObjectCreation = this.handleObjectCreation.bind(this);
    }

    handleObjectCreation(obj) {
        this.props.handleObjectCreation(obj);

    }

    render() {
        return renderObjectListForm(this.props.objectType, this.props.title, this.props.columns, this.props.objectList, this.handleObjectCreation, this.props.selectors);
    }

}

8. Main App component

Now all our components are ready and we can combine them together.
We have to create function which will be handlers for department and user creation. This functions will be updating state object. We will pull then "down" to low level components. For department creation, we need to update additional selector object, which will be used for user creation.  Also we have not to forget to set up in constructor the  initial state with empty objects.


function departmentCreation(department) {
    this.setState(
            prevState => {
                var list = prevState.depList;
                var depSelectors = prevState.selectors;
                var selector = depSelectors.department ? depSelectors.department : [];
                list.push(department);
                selector.push(department.name);
                depSelectors.department = selector;
                this.setState({depList: list});
                this.setState({selectors: depSelectors});

            }
    );
}

function userCreation(user) {
    this.setState(
            prevState => {
                var list = prevState.userList;
                list.push(user);
                this.setState({userList: list});
            }
    );
}

class Body extends Component {

    constructor(props) {
        super(props);
        this.handleDepartmentCreation = departmentCreation.bind(this);
        this.handleUserCreation = userCreation.bind(this);
        this.state = {depList: [], userList: [], selectors: {}};
    }

    render() {
        var depColumns = [{name: "id", label: "Id"}, {name: "name", label: "Name"}];
        var userColumns = [{name: "id", label: "Id"}, {name: "name", label: "Name"}, {name: "emal", label: "Email"}, {name: "department", label: "Department"}];
        return (
                <div>
                    <ObjectList objectList={this.state.depList} handleObjectCreation={this.handleDepartmentCreation} columns={depColumns} objectType="departments" title="Departments" />
                    <ObjectList objectList={this.state.userList} selectors={this.state.selectors} handleObjectCreation={this.handleUserCreation} columns={userColumns} objectType="users" title="Users" />
                </div>
                );
    }
}

class App extends Component {
    render() {
        return (
                <div className="App">
                    <div className="App-header">
                        <img src={logo} className="App-logo" alt="logo" />
                        <h2>Welcome to React</h2>
                    </div>
                    <p className="App-intro">
                        To get started, edit <code>src/App.js</code> and save to reload.
                    </p>
                    <Body/>
                </div>
                );
    }
}


9. The end

ReactJS can make application creation very simple, because it's based on creation of simple blocks which can be developer and tested separately. Full source code can be downloaded from here