Wednesday, April 27, 2016

Let's Relax! Builder Pattern Example and Lombok API

Hi All,

Thanks again for reading my comments over internet.

I am trying to help java developers to know more about implementations and configurations using Java or JBoss Midleware technologies.

Now i would like to show a simple implementation pattern: Builder.
So, let's see the example:

1 - Simple Person class

/**
 * Person simple class information
 *
 * @author alvesfred
 *
 */
public class SimplePerson implements Serializable {

    /**
     * serial
     */
    private static final long serialVersionUID = -978731152684129660L;

    private String name;
    private int age;
    private boolean male;
    private boolean married;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public boolean isMale() {
        return male;
    }

    public void setMale(boolean male) {
        this.male = male;
    }
   
    public boolean isMarried() {
        return married;
    }
   
    public void setMarried(boolean married) {
        this.married = married;
    }
}


2 - Builder Pattern

/**
 * Builder pattern
 *
 * @author alvesfred
 *
 */
public abstract class Builder<T> {
    /**
     * Build
     *
     * @return
     */
    public abstract T build();
}
 

/**
 * Builder pattern class
 *
 * @author alvesfred
 *
 */
public class Person {

    private final String name;
    private final int age;
    private final boolean male;
    private final boolean married;

    public Person(PersonBuilder pfb) {
        this.name    = pfb.name;
        this.age     = pfb.age;
        this.male    = pfb.male;
        this.married = pfb.married;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public boolean isMale() {
        return male;
    }

    public boolean isMarried() {
        return married;
    }

    /**
     * Builder class sample
     *
     * @author alvesfred
     *
     */
    public static class PersonBuilder extends Builder<Person> {
        private final String name;
        private int age;
        private boolean male;
        private boolean married;

        public PersonBuilder(String name) {
            this.name = name;
        }

        public PersonBuilder defineAge(int age) {
            this.age = age;
            return this;
        }

        public PersonBuilder defineMale(boolean male) {
            this.male = male;
            return this;
        }

        public PersonBuilder defineMarried(boolean married) {
            this.married = married;
            return this;
        }

        public Person build() {
            return new Person(this);
        }
    }

    @Override
    public String toString() {
        return "[PERSON] "        + name
                + " - [Age] "     + age
                + " - [Male?] "   + male
                + " - [Married] " + married;
    }

    /**
     * Main
     *
     * @param args
     */
    public static void main(String[] args) {
        Person p = new PersonBuilder("Fred")
            .defineAge(38)
            .defineMale(true)
            .defineMarried(true)
            .build();

        System.out.println(p);
    }
}


A few months ago i see this important API, and i like it so much!
Lombok API is very interesting...have fun!

https://projectlombok.org/

[IMHO] for @Data annotation using lombok, I just recommend override equals and hashCode methods to use HashCodeBuilder and EqualsBuilder (Apache Commons).


Thanks a lot and see you next time!

"Move to Canada/Vancouver - it is my dream! Java/JEE/Middleware development is my work and i love it so much!"


Java EE 6 Performance - Datasource Configuration and Good Hibernate Properties for Oracle Relational Databases

Hello Everyone...
I am back!

In this post i would like to present some configurations to optimize your web application that uses Hibernate 4/5 and Oracle relational database.

Web Applications can require two types of transaction configuration using EJB concepts, Bean management or JTA/Container management transaction. In both case you need to delivery good results on every request...that's your challenge!

So, try to use these configurations over Hibernate and Datasource for JBoss EAP 6.x Middleware:

1 - Modules with JMS, Data Mining, Quartz Jobs, Multithreads - Executors (persistence.xml) or modules that use batch updates over the same transaction - until 1500 rows per request

        <properties>
            <property name="hibernate.show_sql"   value="false"/>
            <property name="hibernate.format_sql" value="false"/>
              <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
             <property name="hibernate.generate_statistics" value="false" />
            <property name="hibernate.connection.release_mode" value="after_transaction" />            <property name="hibernate.transaction.jta.platform"    value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform" />
           <property name="hibernate.jdbc.use_streams_for_binary" value="true" />

            <property name="hibernate.order_inserts" value="true"/>
            <property name="hibernate.order_updates" value="true"/>
            <property name="hibernate.jdbc.fetch_size" value="100"/>
            <property name="hibernate.jdbc.batch_size" value="100"/>            <property name="hibernate.cache.use_second_level_cache" value="false"/>


2 - Web Modules only (frontend) or WebServices (persistence.xml)
Transactions with 100 or 500 rows per request

        <properties>
            <property name="hibernate.show_sql"   value="false"/>
            <property name="hibernate.format_sql" value="false"/>
              <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
             <property name="hibernate.generate_statistics" value="false" />
            <property name="hibernate.connection.release_mode" value="on_close" />            <property name="hibernate.transaction.jta.platform"    value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform" />
             <property name="hibernate.jdbc.use_streams_for_binary" value="true" />

            <property name="hibernate.order_inserts" value="true"/>
            <property name="hibernate.order_updates" value="true"/>
            <property name="hibernate.jdbc.fetch_size" value="50"/>
            <property name="hibernate.cache.use_second_level_cache" value="false"/>


3 - JTA Datasource
(for JMS modules, in most of cases, XA Driver is recommended)

                <datasource jta="true" jndi-name="java:/jdbc/<name>" pool-name="jdbc/<name>" enabled="true" use-ccm="false"
                            statistics-enabled="true">
                        <connection-url>jdbc:oracle:thin:@//<ip>:<port>/<service></connection-url>
                        <driver>oracle</driver>
                        <transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation>
                        <pool>
                            <!-- min 60% of max - dont forget this --> 
                            <min-pool-size>32</min-pool-size>
                        <max-pool-size>46</max-pool-size>
                        <prefill>true</prefill>
                        <flush-strategy>IdleConnections</flush-strategy>

                        </pool>
                        <security>
                            <user-name>xxxx</user-name>
                            <password>xxxx</password>
                        </security>
            <validation>
                <valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleValidConnectionChecker"/>
                <background-validation>true</background-validation>
                <background-validation-millis>120000</background-validation-millis>
                <stale-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleStaleConnectionChecker"/>
                <exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleExceptionSorter"/>
            </validation>
            <timeout>
                <idle-timeout-minutes>1</idle-timeout-minutes>                 </timeout>
            <statement>
                <share-prepared-statements>true</share-prepared-statements>
            </statement>




Tuesday, April 5, 2016

Performance over Hibernate 4 (scroll) and JBoss EAP Datasource Tests

Hi all,
Thanks again for reading my post...

Now, i would like to show you the code above to scroll data using hibernate and how to see the results into JBoss EAP for Datasource jca component.

First of all, let's create the handler class...

public interface RowHibernateHandler<T> extends Serializable {

    /**
     * Do something with the data
     *
     * @param row
     */
    void doWithOneRow(T row);

    // dispose if you like this...
    //void dispose();
}

The handler implementation:

class TestRowHandler implements RowHibernateHandler<Object[]> {
    /**
     * serial
     */
    private static final long serialVersionUID = 1795300378307243234L;

    /**
     * Results
     */
    private List<Object[]> list = new ArrayList<>();
   
    /**
     * Index - removing
     */
    private List<Object[]> listIndexObjects = new ArrayList<>();

    /**
     * Total Count
     */
    private int count = 0;

    @Override
    public void doWithOneRow(Object[] row) {
        list.add(row);
        count++;
    }

    /**
     * Remove
     */
    public void removeIndexObjects() {
        Iterator<Object[]> ite = listIndexObjects.iterator();
        while (ite.hasNext()) {
            list.remove(ite.next());
        }

        listIndexObjects.clear();
    }

    /**
     * Index
     *
     * @param index
     */
    public void indexToRemove(Object[] obj) {
        listIndexObjects.add(obj);
    }

    /**
     * Empty ?
     *
     * @return
     */
    public boolean isEmpty() {
        return list.isEmpty();
    }

    /**
     * Clear
     *
     * @return
     */
    public void clear() {
        list.clear();
        listIndexObjects.clear();
    }

    /**
     * Remove
     *
     * @param i
     */
    public void remove(int i) {
        list.remove(i);
    }

    /**
     * GET
     *
     * @param index
     * @return
     */
    protected Object[] get(int index) {
        return list.get(index);
    }

    /**
     * List
     *
     * @return
     */
    public List<Object[]> getList() {
        return list;
    }

    /**
     * Original Size
     *
     * @return
     */
    public int size() {
        return count;
    }
}

Method using Hibernate/JPA classes (SLSB EJB 3):

    public void createScrollQueryResults(
            CriteriaQuery<Object[]> query, RowHibernateHandler<Object[]> handler) throws Exception {

        TypedQuery<Object[]> typedQuery = entityManager.createQuery(query);

        typedQuery.setFlushMode(FlushModeType.AUTO);
        typedQuery.setHint(org.hibernate.annotations.QueryHints.READ_ONLY, true);
        typedQuery.setHint(org.hibernate.annotations.QueryHints.CACHE_MODE, org.hibernate.CacheMode.IGNORE);
        typedQuery.setHint(org.hibernate.annotations.QueryHints.TIMEOUT_HIBERNATE, 180000); // 3 minutes
        typedQuery.setHint(org.hibernate.annotations.QueryHints.TIMEOUT_JPA, 180000); // 3 minutes
        // fetch with 1000 elements...sometimes it is a terrible choice!! Reduce the value...
        typedQuery.setHint(org.hibernate.annotations.QueryHints.FETCH_SIZE, 1000);

        org.hibernate.Query hibernateQuery =
                typedQuery.unwrap(org.hibernate.Query.class);

        // data will not be rendered over memory...thats nice!!!
        org.hibernate.ScrollableResults cursor =
             hibernateQuery.scroll(org.hibernate.ScrollMode.SCROLL_INSENSITIVE);
      
        // it is possible to see the last page - count objects result
        if (cursor.last()) {
            System.out.println("Total lines: " + cursor.getRowNumber() + 1);
        }
        cursor.first();
        scrollHandleResults(cursor, handler);
    }
   
    private <T extends Serializable> void scrollHandleResults(
            ScrollableResults results, RowHibernateHandler<T> handler) {

        try {
            while (results.next()) {
                T row = (T) results.get(0);
                handler.doWithOneRow(row);
            }
          
        } finally {
            if (results != null) {
                results.close();
            }
        }
    }

How to Monitor and see the results into JBoss EAP...

- Logger

            <logger category="org.hibernate.stat">
                <level name="DEBUG"/>
            </logger>
            <logger category="org.hibernate.loader.Loader"> <!-- warnings sobre lock -->
                <level name="ERROR" />
            </logger>
            <logger category="org.jboss.jca">
                <level name="TRACE"/>
             </logger>
             <logger category="jboss.jdbc.spy">
               <level name="TRACE"/>
            </logger>

- Datasource (Oracle XE driver ojdbc6)

 <datasource jta="true" jndi-name="java:/jdbc/test" pool-name="jdbc/test"
        enabled="true" use-ccm="false" statistics-enabled="true" spy="true">
                    <connection-url>jdbc:oracle:thin:@//localhost:1521/xe</connection-url>
                    <driver>oracle</driver>
                    <transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation>
                    <pool>
                        <min-pool-size>25</min-pool-size>
                        <max-pool-size>40</max-pool-size>
                        <prefill>true</prefill>                       
                        <flush-strategy>IdleConnections</flush-strategy>
                    </pool>
                    <security>
                        <user-name>test</user-name>
                        <password>test</password>
                    </security>
                    <validation>
                        <valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleValidConnectionChecker"/>
                        <stale-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleStaleConnectionChecker"/>
                        <exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleExceptionSorter"/>
                    </validation>
                    <statement>
                        <share-prepared-statements>false</share-prepared-statements>
                    </statement>
                </datasource>



Test it...
   
       CriteriaBuilder builder = entityManager.getCriteriaBuilder();
       CriteriaQuery<Object[]> query = builder.createQuery(Object[].class);
       // TODO fill the query - add predicates...
       final TestRowHandler handlerResults = new TestRowHandler();

       createScrollQueryResults(query, handlerResults);
  
        if (handlerResults.isEmpty()) {
            LOGGER.warning("empty!!");
        }

       // handlerResults.dispose();
 

That's it!!!
Thanks a lot...see you on the next post!
Regards...

"My dream... take an IT project outside Brazil to help people and enjoy with Java technologies (JEE middleware solutions)"