Thursday, November 1, 2018

Java Application accessing Oracle Database by using Hibernate


1. Download Hibernate from http://www.hibernate.org/downloads or mvnrepository.com

2. Configure Hibernate by hibernate.cfg.xml or hibernate.properties
   hibernate.cfg.xml sample for Oracle
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN" 
"http://www.jboss.org/dtd/hibernate/hibernate-configuration-3.0.dtd">
 <!-- // NOTE: if accessing .dtd has a problem, download .dtd to local and refer it from CLASSPATH like below -->
 <!-- <!DOCTYPE hibernate-configuration SYSTEM "classpath://org/hibernate/hibernate-configuration-3.0.dtd"> -->
<hibernate-configuration>
<session-factory> <!-- Oracle -->
<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property> 
<property name="hibernate.connection.url">jdbc:oracle:thin:@server:port:SID</property> 
<property name="dialect">org.hibernate.dialect.Oracle10gDialect</property> 
<property name="hibernate.default_schema">schema_name</property> 
<property name="hibernate.connection.username">user_name</property> 
<property name="hibernate.connection.password">user_password</property>
<property name="hibernate.connection.pool_size">10</property>
<property name="show_sql">true</property> 
<property name="hibernate.current_session_context_class">thread</property> 
<property name="hibernate.jdbc.batch_size">30</property>
</session-factory>
</hibernate-configuration>

   hibernate.properties sample for PostgreSQL
    hibernate.connection.driver_class = org.postgresql.Driver
    hibernate.connection.url = jdbc:postgresql://localhost:5432/mydatabase
    hibernate.connection.username = myuser
    hibernate.connection.password = secret
    hibernate.c3p0.min_size=5
    hibernate.c3p0.max_size=20
    hibernate.c3p0.timeout=1800
    hibernate.c3p0.max_statements=50
    hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect

3. Create a Hibernate Java project in Maven with required dependencies, including:
    database client library files. e.g. ojdbc*.jar for Oracle, postgresql*.jar for PostgreSQL
hibernate-core
hibernate-entitymanager for Hibernate JPA implementation
hibernate-ehcache for using Hibernate cache mechenism
    e.g. in pom.xml
    <properties>
        <hibernate.version>4.3.5.Final</hibernate.version> <!-- bundled with Wildfly 8.1.0 -->
    </properties>
    <dependencies>
      <dependency>
        <groupId>com.oracle</groupId>
        <artifactId>ojdbc</artifactId>
        <version>5.0</version>
      </dependency>
      <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>${hibernate.version}</version>
      </dependency>
      <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>${hibernate.version}</version>
      </dependency>
      <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-ehcache</artifactId>
        <version>${hibernate.version}</version>
      </dependency>
  </dependencies>

4. Create an Entity object mapped with the data structure (e.g. a table or a view) in DB
    For an example of Student Table in DB, the entity class defined as Student in below:
@Entity
 @Table(name="Student_Table")
public class Student {
 @Id
@Column(name="Student_Id")
private String studentId;

@Column(name="First_Name")
private String firstName;

@Column(name="Last_Name")
private String lastName;

public String getStudentId(){ return studentId; }
public void setStudentId(String id) { this.studentId = id; }

public String getFirstName(){ return firstName; }
public void setFirstName(String name) { this.firstName = name; }

public String getLastName(){ return lastName; }
public void setLastName(String name) { this.lastName = name; }
}

5. Map the entity class in hibernate.cfg.xml by adding the following in <session-factory />
    <mapping class="org.freecode.demo.entity.Student" /> <!-- // full class name with package -->

6. Access DB through Hibernate
    public static void main(String[] args) {
String configFile = "hibernate.cfg.xml"; // load Hibernate configuration
Configuration cfg = new Configuration();
cfg.configure(configFile);
StandardServiceRegistryBuilder ssrb = new StandardServiceRegistryBuilder();
ssrb.applySettings(cfg.getProperties());
ServiceRegistry sr = ssrb.build();
SessionFactory sf = cfg.buildSessionFactory(sr); // initialize a session factory
Session s = sf.openSession();
// Session s = sf.getCurrentSession(); // initialize a DB session
// Transaction tx = null;
try {
// tx = s.beginTransaction();
List<ProjectCause> causes = s.createQuery("FROM Student").list(); // create a Hibernate Query to get all student objects from the DB session
// tx.commit();
if (causes != null) {
for (ProjectCause c : causes) {
System.out.println("Student: " + c.getStudentId() + " - " c.getFirstName() + " " + c.getLastName());
}
}
}
catch (HibernateException he) {
he.printStackTrace();
// tx.rollback();
}
finally {
if (s.isOpen()) {
            s.close();
}
}
}

7. Use Hibernate JPA Implementation by creating JPA descriptor - persistence.xml
    <?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
  <persistence-unit name="Hibernate_JPA_Unit" transaction-type="RESOURCE_LOCAL"> <!-- non EJB type -->
<description>Persistence Unit for JPA Implementation</description>
<provider>org.hibernate.ejb.HibernatePersistence</provider>
  <class>org.freecode.demo.entity.Student</class> <!-- need to map the class for WAR, EAR -->
<properties>
  <property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver" />
  <property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@server:port:SID" />
  <property name="javax.persistence.jdbc.user" value="db user" />
  <property name="javax.persistence.jdbc.password" value="db password" />
  <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
  
  <!-- for caching, require hibernate-ehcache.jar -->
  <property name="hibernate.cache.use_second_level_cache" value="true"/>
  <property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.EhCacheRegionFactory"></property>
  <property name="hibernate.cache.use_query_cache" value="true"></property>

  <property name="hibernate.jdbc.batch_size" value="30"/>
  <property name="hibernate.show_sql" value="true" />
  <!-- logger: org.hibernate.SQL, org.hibernate.engine.query, org.hibernate.type, org.hibernate.jdbc -->
  <property name="hibernate.format_sql" value="true"/>
  <property name="hibernate.transaction.flush_before_completion" value="true" />
</properties>
  </persistence-unit>
</persistence>

8. Access DB through Hibernate JPA
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("Hibernate_JPA_Unit"); // unit name is defined in persistence.xml
EntityManager em = emf.createEntityManager();

try {
Query qry = em.createQuery("SELECT c FROM Student c");
List<ProjectCause> students = qry.getResultList();
if (causes != null) {
for (Student std : students) {
System.out.println(std.getStudentId() + " - " + std.getFirstName() + " " + c.getLastName());
}
}
}
catch (Exception ex) {
ex.printStackTrace();
}
finally {
if (em.isOpen()) {
em.close();
}
em = null;
if (emf.isOpen()) {
emf.close();
}
emf = null;
}

Monday, October 22, 2018

Configure Different Database Connections in Wildfly/JBoss Application Server


1. download and copy the database driver libraries
   For Oralce, search ojdbc from Oracle, https://www.oracle.com/technetwork/database/features/jdbc/jdbc-ucp-122-3110062.html
   For MS SQL Server, https://www.microsoft.com/en-us/download/details.aspx?id=56615
   For MySQL, https://dev.mysql.com/downloads/connector/j/
   For PostgreSQL, https://jdbc.postgresql.org/download.html

2. install and configure the database drivers in Wildfly/JBoss system modules
   For Oracle, copy ojdbc?.jar (e.g. ojdbc7.jar) to %JBOSS_HOME%/modules/system/layers/base/com/oracle/main (create folders when necessary). Create a configuration file, module.xml in the same folder with the driver file.
       <?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="com.oracle">
  <resources>
<resource-root path="ojdbc5.jar"/>
  </resources>
  <dependencies>
<module name="javax.api"/>
<module name="javax.transaction.api"/>
  </dependencies>
</module>

   For MS SQL Server, copy mssql-jdbc-x.x.x.jre?.jar (e.g. mssql-jdbc-6.2.2.jre7) into %JBOSS_HOME%/modules/system/layers/base/com/microsoft/sqlserver/main. Create a configuration file, module.xml in the same folder with the driver file.
       <?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="com.microsoft.sqlserver">
  <resources>
<resource-root path="mssql-jdbc-6.2.2.jre7.jar"/>
  </resources>
  <dependencies>
<module name="javax.api"/>
<module name="javax.transaction.api"/>
<module name="javax.xml.bind.api"/>
  </dependencies>
</module>

   For MySQL, copy mysql-connector-java-x.x.x.jar (e.g. mysql-connector-java-5.1.44.jar) into %JBOSS_HOME%/modules/system/layers/base/com/mysql/main. Create a configuration file, module.xml in the same folder with the driver file.
   <?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="com.mysql">
  <resources>
<resource-root path="mysql-connector-java-5.1.44.jar"/>
  </resources>
  <dependencies>
<module name="javax.api"/>
<module name="javax.transaction.api"/>
  </dependencies>
</module>

For PostgreSQL, copy postgresql-x.x.x.jre?.jar (e.g. postgresql-9.4.1209.jre6.jar) into %JBOSS_HOME%/modules/system/layers/base/org/postgresql/main. Create a configuration file, module.xml in the same folder with the driver file.
    <?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="org.postgresql">
  <resources>
<resource-root path="postgresql-9.4.1209.jre6.jar"/>
  </resources>
  <dependencies>
<module name="javax.api"/>
<module name="javax.transaction.api"/>
  </dependencies>
</module>

3. Configure the database drivers and data sources in Wild/JBoss Application Server.
    Open and update the Wildfly/JBoss configuration file (e.g. standalone.xml) by adding the database driver and data source information like the following: (Note: make sure the driver name, module name and etc. match with the configuration previously mentioned)

        <subsystem xmlns="urn:jboss:domain:datasources:2.0">
            <datasources>
                ... ...
<!-- // Connection Pool of Oracle. java:/jdbc/myoracle is used in applications -->
                <datasource jndi-name="java:/jdbc/myoracle" pool-name="myOraclePool" enabled="true" use-java-context="true">
                    <connection-url>jdbc:oracle:thin:@server_name:1521:SID</connection-url>
                    <driver>oracle_driver</driver>
                    <security>
                        <user-name>db_user_name</user-name>
                        <password>db_user_password</password>
                    </security>
                </datasource>

<!-- // Connection Pool for MS SQL Server Express -->
                <datasource jndi-name="java:/jdbc/MsSQLSvrDS" pool-name="MsSQLPool" enabled="true" use-java-context="true">
                    <connection-url>jdbc:sqlserver://server_name\SQLEXPRESS:54126;databaseName=TestDB;integratedSecurity=true;</connection-url>
                    <driver-class>com.microsoft.sqlserver.jdbc.SQLServerDriver</driver-class>
                    <driver>sqlserver_driver</driver>
                    <pool>
                        <min-pool-size>5</min-pool-size>
                        <max-pool-size>10</max-pool-size>
                    </pool>
                    <security>
                        <user-name>db_user_name</user-name>
                        <password>db_user_password</password>
                    </security>
                </datasource>

<!-- // Connection Pool for MySQL -->
                <datasource jndi-name="java:/jdbc/MySQLDS" pool-name="MySQLDS" enabled="true" use-java-context="true">
                    <connection-url>jdbc:mysql://server_name:3306/my_test_db</connection-url>
                    <driver>mysql_driver</driver>
                    <pool>
                        <min-pool-size>1</min-pool-size>
                        <max-pool-size>5</max-pool-size>
                    </pool>
                    <security>
                        <user-name>db_user_name</user-name>
                        <password>db_user_password</password>
                    </security>
                </datasource>

                <!-- // Connection Pool for MySQL -->
                <datasource jta="false" jndi-name="java:/jdbc/PostgreSQLDS" pool-name="PostgreSQLDS" enabled="true" use-ccm="false">
                    <connection-url>jdbc:postgresql://server_name:5432/my_test_db</connection-url>
                    <driver-class>org.postgresql.Driver</driver-class>
                    <driver>postgresql_driver</driver>
                    <pool>
                        <min-pool-size>1</min-pool-size>
                        <max-pool-size>5</max-pool-size>
                    </pool>
                    <security>
                        <user-name>db_user_name</user-name>
                        <password>db_user_password</password>
                    </security>
                </datasource>
                <drivers>
                    ... ...
                    <!-- // Oracle Driver -->
    <driver name="oracle_driver" module="com.oracle">
                        <driver-class>oracle.jdbc.OracleDriver</driver-class>
                    </driver>

                    <!-- // MS SQL Server Driver -->
                    <driver name="sqlserver_driver" module="com.microsoft.sqlserver">
                        <driver-class>com.microsoft.sqlserver.jdbc.SQLServerDriver</driver-class>
                    </driver>
                   
                    <!-- // MySQL Driver -->
                    <driver name="mysql_driver" module="com.mysql">
                        <driver-class>com.mysql.jdbc.Driver</driver-class>
                    </driver>

                    <!-- // PostgreSQL Driver -->
                    <driver name="postgresql_driver" module="org.postgresql">
                        <driver-class>org.postgresql.Driver</driver-class>
                    </driver>
                </drivers>
            </datasources>
        </subsystem>

4. Start the Wildfly/JBoss application server and verify the database connectivities from the server logs.

5. Use the connection pool for JPA.
    Find and update persistence.xml as following in the application folder, /src/main/resources/META-INF/persistence.xml.

<persistence-unit name="Persistence_Unit_Name"> <!-- referenced in application //-->
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>PostgreSQLDS</jta-data-source> <!-- // for example of PostgreSQL datasource defined in Wildfly/JBoss -->
<properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
            <property name="hibernate.show_sql" value="false" /> <!-- Debugging purpose //-->
            <property name="hibernate.generate_statistics" value="false"/> <!-- Debugging purpose //-->
        </properties>
</persistence-unit>

If not use Connection Pool defined in Wildfly/JBoss application server, need to specify the database connection information in preperties as well.
<persistence-unit name="Persistence_Unit_Name" transaction-type="RESOURCE_LOCAL"> <!-- referenced in application //-->
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <properties>
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:postgresql://server_name:5432/my_test_db" />
            <property name="javax.persistence.jdbc.user" value="db_user_name" />
            <property name="javax.persistence.jdbc.password" value="db_user_password" />

     <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
        </properties>
</persistence-unit>

Saturday, October 20, 2018

Wildfly/JBoss Application Server Setup Guide

1. Download from http://download.jboss.org/wildfly/12.0.0.Final/wildfly-12.0.0.Final.zip
   Note: Wildfly is a community version of JBoss Application Server. If you want an enterprise version, look for JBoss EAP(license required) from Redhat.

2. Install Wildfly 12.0 by unzip the binary package to a local folder, c:\wildfly-12.0.0-Final.

3. Set up environment in Windows System Environment or a batch file
     c:\> SET JBOSS_HOME=c:\wildfly-12.0.0-Final
     c:\> SET PATH=%PATH%;%JBOSS_HOME%/bin

4. Start up Wildfly/JBoss Server
     c:\wildfly-12.0.0-Final\bin> standalone.bat
     NOTE: if there is any port numbers already in use, update the port number in %JBOSS_HOME%/standalone/configuration/standalone.xml (the socket-binding section at the bottom of the configuration file)

5. Check logs in %JBOSS_HOME%/standalone/log

6. Test Wildfly/JBoss Application Server
     In web browser, access http://localhost:8080/, a default Wildfly page should show up.

7. (Hot) deploy a web application archive package (*.war file) to the Wildfly/JBoss standalone instance.
     Copy the .war file (e.g. WebDesignDemo.war) into %JBOSS_HOME%/standalone/deployments while the application server is running. The server will unpack the application into a folder with the name of the .war file.
     The application context name is normally same as the .war file name. The HTTP URL is http://localhost:8080/<Context Name> (e.g. http://localhost:8080/WebDesignDemo).
     Without specifying a page name in the URL, the server will look at the default home page, e.g. index.html or index.jsp in the application folder.
     To check if the application deployment is successful, go to the deployment folder, you should see a file with the extension of .deployed. If failed, open the file and investigate the error message.

8. Shut down Wildfly/JBoss Application Server
     Just press Ctrl+C in the application server console window, or close the MS-DOS console with the running server.
     Note: if you have any strange issues when shutting down the server, use Windows Task Manager to kill the corresponding java.exe process.

Friday, October 19, 2018

Apache Tomcat Application Server Setup Guide


1. Download from https://tomcat.apache.org/download-90.cgi

2. Install Apache Tomcat 9.x by unzip the binary package to a local folder, c:\apache-tomcat-9.0.12.

3. Set up environment in Windows System Environment or a batch file
     c:\> SET CATALINA_HOME=c:/apache-tomcat-9.0.12
     c:\> SET PATH=%PATH%;%CATALINA_HOME%/bin

4. Start up Tomcat Application Server
     c:\apache-tomcat-9.0.12\bin> startup.bat
     NOTE: if there is any port numbers already in use, update the port number in %CATALINA_HOME%/conf/server.xml

5. Check logs in %CATALINA_HOME%/logs/

6. Test Tomcat Application Server
     In web browser, access http://localhost:8080/, a default Tomcat page (physically in %CATALINA_HOME%\webapps\ROOT\index.jsp) should show up.

7. (Hot) deploy a web application archive package (*.war file)
     Copy the .war file (e.g. WebDesignDemo.war) into %CATALINA_HOME%/webapps while the application server is running. The server will unpack the application into a folder with the name of the .war file.
     The application context name is normally same as the .war file name. The HTTP URL is http://localhost:8080/<Context Name> (e.g. http://localhost:8080/WebDesignDemo).
     Without specifying a page name in the URL, the server will look at the default home page, e.g. index.html or index.jsp in the application folder.

8. Shut down Tomcat Application Server
     c:\apache-tomcat-9.0.12\bin> shutdown.bat
     Alternatively, just press Ctrl+C in the application server console window

Tuesday, October 16, 2018

Set up PostgresSQL database

1. Download from https://www.enterprisedb.com/download-postgresql-binaries

2. Install PostgreSQL database by unzip the binary package to a local folder, c:\pgsql. Alternatively, a GUI-installation can be downloaded for easier installation.

3. Set up environment in Windows System Environment or a batch file. NOTE: you may need to create a subfolder called \data
     c:\> SET PGDATA=c:\pgsql\data
     c:\> SET PATH=%PATH%;c:\pgsql\bin

4. Initialize DB (Note: without SET PGDATA, need to add -D c:\pgsql\data when calling initdb). For authentication method, you can choose scram-sha-256, md5 or password(in plain text, not recommended due to the "sniff" attack)
     c:\pgsql> initdb --auth-local=scram-sha-256

5. Start up DB service (Note: -l is to specify the log file).
     c:\pgsql> pg_ctl -l logfile start
     (in Ubuntu) systemctl start postgresql
6. Create a database
     c:\pgsql> createdb mydb

7. Create a DB user (-s option is for super user)
    c:\pgsql> createuser -s postgres

8. Connect to the database from Postgres client console, mydb
     c:\pgsql> psql -h localhost -d mydb

9. List instances from a database, mydb (Note: use parameter \l or \list)
     mydb# \list

10. Connect/switch to another database, postgres (Note: use parameter \c or \connect)
     mydb# \connect postgres

11. List all tables from the current database
     mydb# SELECT * FROM Information_Schema.tables WHERE table_type = 'BASE TABLE' AND table_schema NOT IN ('pg_catalog', 'information_schema');

12. List all fields of a table
    mydb# \d test_user_tab;
    or
    mydb# SELECT * FROM Information_Schema.columns WHERE table_name = 'test_user_tab';

13. Quit Postgres client console (Note: use parameter \q or \quit)
     mydb# \quit

14. Change password in Postgres client console
     mydb# \password new_password

15. Check DB server Status
     c:\pgsql> pg_ctl status
     (in Ubuntu) systemctl status postgresql
16. Shut down DB Server
     c:\pgsql> pg_ctl stop
     (in Ubuntu) systemctl stop postgresql
17. Show help information (use --help in the MS-DOS command; or \? in Postgres client console)
     c:\pgsql> psql --help

18. Common SQL statements
     CREATE DATABASE my_db; -- create a database
     CREATE SCHEMA demo_sch; --create a schema
     CREATE USER xuser PASSWORD 'xuser123'; --create a database role/user
     GRANT ALL ON SCHEMA demo_sch TO xuser; --grant all permissions of a schema to a user
     GRANT ALL ON ALL TABLES IN SCHEMA demo_sch TO xuser; --grant all permission of all tables in a schema to a user
     ALTER USER xuser WITH PASSWORD 'new_password'; --change user password

     CREATE TABLE test_user_tab (name VARCHAR(10), age INT, registered_at TIMESTAMP, balance DECIMAL(10,2)); --create a table named test_user_tab
     
     INSERT INTO test_user_tab (name, age, registered_at, balance) VALUES ('jon', 30, TO_TIMESTAMP('1988-01-01 13:55:55','YYYY-MM-DD HH24:MI:SS'), 1234.56); --insert a record into the table
     SELECT * FROM test_user_tab; --query the table
     UPDATE test_user_tab SET name = 'jonathan' WHERE name = 'jon';
     SELECT name, age, TO_CHAR(registered_at, 'YYYY-MM-DD HH24:MI'), balance FROM test_user_tab; --query the table by specific columns
     DELETE FROM test_user_tab WHERE name = 'jonathan';
     DROP TABLE test_user_tab;

19. Reset database user password (version 12)
  • open /etc/postgresql/12/main/pg_hba.conf and update the following line by replacing md5 to trust, so no password required
 local   all             postgres                                md5
  • restart postgresql database
  • login postgresql using the DB user id without needing a password. e.g. postgres
  • run the following SQL to change/reset the password
    • ALTER USER postgres WITH PASSWORD 'newpassword';
  • open /etc/postgresql/12/main/pg_hba.conf and revert the previous change from trust back to md5
  • restart the database again