Wednesday, May 4, 2016

Hibernate/JPA Entity Model

Hi All,

Thanks again to stay here reading my post.

I would like to help other developers to solve problems about Java and middleware implementations.

If you have any doubts or problems about Java/JEE or JBoss Midleware feel free to contact me (fredericocerqueiraalves@gmail.com). It will be a pleasure to help you.

Now, i would like to show you a model implementation to use hibernate entity beans.

These classes are implemented to support hibernate first or second level cache, audit with envers and native or named queries.

So, let's see...

- Base Model

package br.com.alvesfred.entity;
 

import java.io.Serializable;

/**
 * Base Model Interface
 *
 * @author alvesfred
 *
 */
public interface BaseModel<ID> extends Serializable {

    /**
     * Set ID definition
     *
     * @param id
     */
    void setId(ID id);
   
    /**
     * Get ID
     *
     * @return
     */
    ID getId();
}


- Entity Base Model

package br.com.alvesfred.entity;

import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;

/**
 * Model for Entities
 *
 * @author alvesfred
 *
 * @param <ID>
 */
@MappedSuperclass
public abstract class BaseModelEntity<ID> implements BaseModel<ID> {

    /**
     * serial
     */
    private static final long serialVersionUID = 3958601406206249649L;

    //@Id
    //@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "default_id_generator")
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "hilo_sequence_generator")
    @GenericGenerator(
            name       = "hilo_sequence_generator",
            strategy   = "org.hibernate.id.enhanced.SequenceStyleGenerator",
            parameters = { // default parameters
                    @Parameter(name = "sequence_name",  value = "sq_id"),
                    @Parameter(name = "initial_value",  value = "1"),
                    @Parameter(name = "increment_size", value = "1"),
                    @Parameter(name = "optimizer",      value = "hilo")
    })
    protected ID id;

    public BaseModelEntity() {
    }

    public BaseModelEntity(ID id) {
        setId(id);
    }

    public ID getId() {
        return id;
    }

    public void setId(ID id) {
        this.id = id;
    }

    @Override
    public int hashCode() {
        HashCodeBuilder hcb = new HashCodeBuilder();
        hcb.append(this.id);

        return hcb.toHashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null || obj.getClass().isAssignableFrom(BaseModelEntity.class)) {
            return false;
        }

        @SuppressWarnings("unchecked")
        BaseModelEntity<ID> other = (BaseModelEntity<ID>) obj;

        EqualsBuilder eb = new EqualsBuilder();
        eb.append(this.getId(), other.getId());
       
        return eb.isEquals();
    }
   
}


- Version (Entity Base Model)

 package br.com.alvesfred.entity;

import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import javax.persistence.Version;

/**
 * Lock version entity - base model
 *
 * @author alvesfred
 *
 * @param <ID>
 * @param <VERSION>
 */
@MappedSuperclass
public abstract class BaseModelVersionEntity<ID> extends BaseModelEntity<ID> {

    /**
     * serial
     */
    private static final long serialVersionUID = 9205887194329558055L;

    //@Generated(GenerationTime.NEVER)
    @Version
    @Column(name = "versionId", nullable = false)
    private Long version;

    public Long getVersion() {
        return (this.version != null) ? this.version : this.hashCode();
    }

    public void setVersion(Long versao) {
        this.version = versao;
    }
}


- Finally Entity Class

 package br.com.alvesfred.entity;

import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.ColumnResult;
import javax.persistence.Entity;
import javax.persistence.Lob;
import javax.persistence.NamedNativeQueries;
import javax.persistence.NamedNativeQuery;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.QueryHint;
import javax.persistence.SequenceGenerator;
import javax.persistence.SqlResultSetMapping;
import javax.persistence.SqlResultSetMappings;
import javax.persistence.Table;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.envers.Audited;

@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) // using JTA by container
@Entity
@Audited
@Table(name="person")
@SequenceGenerator(name = "hilo_sequence_generator", sequenceName = "seq_id_person", allocationSize = 1)
@AttributeOverrides({
    @AttributeOverride(name="id", column=@Column(name = "person_id", unique = true, nullable = false, scale = 0)),
})

@NamedQueries({
    @NamedQuery(
            name  = PersonEntity.LIST_BY_ID_NAME,
            query = "select new PersonEntity(p.id) "
                  + "from PersonEntity p "
                  + "where p.name = :name",
            hints = {
                    @QueryHint (name="org.hibernate.cacheable", value="true"),
            }
    ),
})

@NamedNativeQueries(
        value = {
            @NamedNativeQuery(
                name  = PersonEntity.LIST_NATIVE_BY_NAME,
                query = PersonEntity.SQL_NATIVE_BY_NAME,
                resultSetMapping = PersonEntity.MAPPING_NATIVE_BY_NAME),
})

@SqlResultSetMappings(
        value = {
            @SqlResultSetMapping(      
                    name    = PersonEntity.MAPPING_NATIVE_BY_NAME,
                    columns = {
                        @ColumnResult(name="size")}),
        }
)
public class PersonEntity extends BaseModelVersionEntity<Long> {

    private static final long serialVersionUID = -1355055022303449688L;

    // Named Queries
    public static final String LIST_BY_ID_NAME = "PersonEntity.listByIdName";

    // Native Named Queries
    public static final String LIST_NATIVE_BY_NAME = "PersonEntity.nativeListByIdName";

    // SQL
    protected static final String SQL_NATIVE_BY_NAME =
            " select count(*) as size "
          + " from person "
          + " where name = :name ";

    // MAPPING
    public static final String MAPPING_NATIVE_BY_NAME = "PersonEntity.mappingListByIdName";

    @Lob
    @Column(name = "jsonInfo", nullable = false)
    private String jsonInfo; // a complete file text information, using json jackson parser
   
    @Column(name = "name", nullable = false)
    private String name;

    @Column(name = "age", nullable = true)
    private int age;

}
 

That's it!
Thanks a lot and feel free to contact me for any help.

See you soon...

Sunday, May 1, 2016

How to Analyse Java Performance using Red Hat Links

Hi All,

I would like to present links that I use to analyse java performance.
These links are important to know some details about JVM, but you need to subscribe on Red Hat Access Portal to see the details.

[IMHO] To subscribe on Red Hat Access Portal is a important action if you deploy applications over JBoss EAP. On this site, you can obtain a lot of concepts about JBoss and how to solve problems, especially for performance issues on your application running to JVM over JBoss EAP.

So, I enumerate some links to help you with Java and JBoss issues. These links help me a lot!

- Java Application High CPU

https://access.redhat.com/node/24830
https://access.redhat.com/solutions/46596


- Thread Dump

https://access.redhat.com/solutions/18178
https://access.redhat.com/solutions/317143

- Java Garbage Collection Performance

https://access.redhat.com/articles/1192773
https://access.redhat.com/node/19932
https://access.redhat.com/labs/garbagedog/
https://access.redhat.com/solutions/23735

- Application Unresponsive
https://access.redhat.com/solutions/18266
https://docs.jboss.org/author/display/AS7/High+Availability+Guide

- JVM Conf. Tool
https://access.redhat.com/labs/jvmconfig

If you have difficulties to know about java memory leak, I just suggest to read about jmap, jhat and MAT (Eclipse Memory Analyser). These tools are so important to detect a lot of issues about your application running on java virtual machine.

Thanks a lot for reading my post.
See you!!!


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)"