Hibernate 5 Core + FlexyPool - java

I'm trying to develop an Hibernate 5 Core application and I'm using hibernate.cfg.xml to build the SessionFactory. For DB connection, I'm using HikariCP connection pooling but I wanted to retrieve some metrics using FlexyPool.
My current hibernate.cfg.xml is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- HikariCP database connection properties and pool configuration -->
<property name="hibernate.hikari.dataSourceClassName">org.postgresql.ds.PGSimpleDataSource</property>
<property name="hikari.dataSource.serverName">192.168.1.1</property>
<property name="hikari.dataSource.portNumber">5432</property>
<property name="hikari.dataSource.databaseName">dbtest</property>
<property name="hikari.dataSource.user">dbuser</property>
<property name="hikari.dataSource.password">dbpass</property>
<property name="hikari.dataSource.reWriteBatchedInserts">true</property>
<!-- Maximum number of actual connection in the pool, including both idle and in-use connections -->
<property name="hibernate.hikari.maximumPoolSize">10</property>
<!-- Minimum number of idle connections in the pool -->
<property name="hibernate.hikari.minimumIdle">2</property>
<!-- Maximum time that a connection is allowed to sit idle in the pool (in milliseconds). Default: 600000 (10 minutes) -->
<property name="hibernate.hikari.idleTimeout">300000</property>
<!-- Maximum waiting time for a connection from the pool (in milliseconds). Default: 30000 (30 seconds) -->
<property name="hibernate.hikari.connectionTimeout">20000</property>
<!-- Maximum lifetime of a connection in the pool (0 indicates infinite lifetime), subject of course to the idleTimeout setting
(in milliseconds). Default: 1800000 (30 minutes) -->
<property name="hibernate.hikari.maxLifetime">600000</property>
<!-- Controls the amount of time that a connection can be out of the pool before a message is logged indicating a possible
connection leak (in milliseconds). Default: 0 -->
<property name="hibernate.hikari.leakDetectionThreshold">30000</property>
<!-- Select our SQL dialect -->
<!-- Dialect is required to let Hibernate know the Database Type, MySQL, Oracle, etc.
Hibernate 4 automatically figure out Dialect from Database Connection Metadata -->
<property name="hibernate.dialect">org.hibernate.dialect.PostgreSQL10Dialect</property>
<!-- Specifies when Hibernate should release JDBC connections -->
<!-- Values: auto (default) | on_close | after_transaction | after_statement -->
<property name="hibernate.connection.release_mode">auto</property>
<!-- Set the current session context -->
<!-- This option is only needed if using getCurrentSession()
org.hibernate.HibernateException: No CurrentSessionContext configured! -->
<property name="hibernate.current_session_context_class">thread</property>
<!-- Set the default Flush Mode -->
<!-- This option will set the flush mode on Hibernate
Values: AUTO (default) | COMMIT | ALWAYS | MANUAL -->
<property name="hibernate.flushMode">AUTO</property>
<!-- Set JDBC batch size -->
<property name="hibernate.jdbc.batch_size">20</property>
<!-- Hibernate orders the SQL insert statements by entity type -->
<property name="hibernate.order_inserts">true</property>
<!-- Hibernate orders the SQL update statements by entity type -->
<property name="hibernate.order_updates">true</property>
<!-- Set this property to true if your JDBC driver returns correct row counts from executeBatch().
It is usually safe to turn this option on. Hibernate will then use batched DML for automatically
versioned data. Defaults to false. -->
<property name="hibernate.batch_versioned_data">true</property>
<!-- Echo the SQL to stdout -->
<!-- Outputs the SQL queries to stdout, should be disabled in Production
(there are better ways to output SQL statements) -->
<property name="hibernate.show_sql">false</property>
<!-- Show SQL formatted -->
<property name="hibernate.format_sql">true</property>
<!-- Database schema handle on startup -->
<!-- Values: create | validate | update | create-drop
create
validate - Validate and export schema DDL to the database
update
create-drop -->
<property name="hibernate.hbm2ddl.auto">validate</property>
<!-- Tell Hibernate to generate statistics -->
<!-- (will write one multi-line log statement with summarized statistical information at the end of the session).
This will be written to logfile through logger org.hibernate.stat = DEBUG -->
<property name="hibernate.generate_statistics">true</property>
<!-- Log slow DB queries that take longer than a specific duration (ms) -->
<!-- This will be written to logfile through logger org.hibernate.SQL_SLOW = INFO -->
<property name="hibernate.session.events.log.LOG_QUERIES_SLOWER_THAN_MS">1000</property>
</session-factory>
</hibernate-configuration>
I've read the FlexyPool documentation on how to initialize it for HikariCP but don't know where to start. Any help?

You can take a look into the configuration that is used for tests in Hibernate: https://github.com/hibernate/hibernate-orm/blob/main/hibernate-hikaricp/src/test/resources/hibernate.properties

Related

Caused by: org.postgresql.util.PSQLException: database doesn't exist when trying to auto-create database

I have this hibernate.cfg.xml:
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">org.postgresql.Driver</property>
<property name="connection.url">
jdbc:postgresql://localhost/DatabaseName?createDatabaseIfNotExist=true
&useUnicode=yes&characterEncoding=UTF-8
</property>
<property name="connection.username">postgres</property>
<property name="connection.password">password</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">5</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.PostgreSQL9Dialect</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.internal.NoCachingRegionFactory</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
<mapping class="com.main.User"/>
</session-factory>
</hibernate-configuration>
which is supposed to create both tables (for the User entity and the database DatabaseName). However, it doesn't create a database and fails with an error on this line:
sessionFactory = configuration.buildSessionFactory();
What can I do to make it autocreate database titled DatabaseName?
To create database you have to create is manually you can use IDEs for that or cmd to create your DB
And To create Tables you can use create in place of update
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">create</property>
It will create a schema and then you will use an update for the next startup if you don`t want to recreate your tables

Hibernate 5.2 encrypt configuration properties

In my application build on Hibernate 5.2.11 there are many hibernate configuration file with username, password and connection url.
I would like to encrypt that data.
My configuration file is like this:
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="connection.url">jdbc:oracle:localhos</property>
<property name="connection.username">username</property>
<property name="connection.password">passowrd123</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">2</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.Oracle12cDialect</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">false</property>
</session-factory>
</hibernate-configuration>
Any suggestion?
Use a property placeholder then add your database config to a properties file on the server:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>file:${configDir}/database.properties</value>
</property>
</bean>
Then
<property name="connection.url">${url}</property>
<property name="connection.username">${username}</property>
<property name="connection.password">${passowrd}</property>
Then your database.properties which is securely on the server will be
url=jdbc:oracle:localhost
usuername=username
password=passowrd123
Then when you start your java app add a system parameter to define the configDir location, for example:
.... -DconfigDir=/opt/config
See examples here
Generally - encrypting/hiding anything what resides on the client's side (workstation/mobile/..) you can consider more like obfuscation or encoding.
In theory - you may set the Hibernate properties programatically (see Setting properties programmatically in Hibernate) reading your data from an encrypted file.
The problem is - where do you put your encryption keys? The keys has to be available to the application anyway somewhere.

Error switching from Hibernate Annotations to hbm.xml file

So while working on my project I originally used Hibernate Annotations #Entity, #Table, #Column, #SequenceGenerator, and #GeneratedValue in my java class and was able to successfully add items to my Oracle database.
Now I'm trying to replicate the same thing, but using a *.hbm.xml file and encountering problems.
Here is the original Java Class code with the annotations commented out:
//#Entity
//#Table (name="client")
#SequenceGenerator(name="seq_client",sequenceName="BIMB2013WMMEE.seq_client",
allocationSize=1, initialValue=1)
public class Client {
//Fields
//#Id
//#GeneratedValue(strategy=GenerationType.SEQUENCE)
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="seq_client")
//#Column(name="CLIENT_ID")
private int id;
//#Column(name="CLIENT_NAME")
private String clientName;
//#Column(name="CLIENT_CODE")
private String clientCode;
Here is the corresponding hbm.xml file which is located in the src directory of my project.
<hibernate-configuration>
<session-factory>
<!-- JDBC Database connection settings -->
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="connection.url">jdbc:oracle:thin:#endeavour.us.manh.com:1523/pso11r2f</property>
<property name="connection.username">BIMB2013WMMEE</property>
<property name="connection.password">BIMB2013WMMEE</property>
<!-- JDBC connection pool settings ... using built-in test pool -->
<property name="connection.pool_size">1</property>
<!-- Select our SQL dialect -->
<property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
<!-- Echo the SQL to stdout -->
<property name="show_sql">true</property>
<!-- Set the current session context -->
<property name="current_session_context_class">thread</property>
</session-factory>
</hibernate-configuration>
Finally here is the Eclipse Error code:
Exception in thread "main" org.hibernate.MappingException: Unknown entity: com.luv2code.hibernate.demo.entity.Client
I didn't make any changes to the class that is actually creating the object and adding it to the database via a session... do I need to?
Thanks for the help!!
The xml file which you have shown is hibernate configuration file it is not hbm.xml file.
You have to make "classname.hbm.xml" file for each persistent entity you make - in your case it is your Client class. so you have to make a Client.hbm.xml file. After that you have to add that resource to your configuration file and Hibernate Utility file. You might find this helpful.
http://www.mkyong.com/hibernate/how-to-add-hibernate-xml-mapping-file-hbm-xml-programmatically/
I think you may have forgotten mapping tags to list all the resources that are using hibernate persistence in your project.
Here's an example :
hibernate.cfg.xml
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">org.h2.Driver</property>
<property name="connection.url">jdbc:h2:file:db/personh2db;DB_CLOSE_DELAY=-1;MVCC=TRUE</property>
<property name="connection.username">sa</property>
<property name="connection.password"/>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.H2Dialect</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">create</property>
<mapping resource="com/example/model/Person.hbm.xml"/>
<mapping resource="com/example/model/Properties.hbm.xml"/>
</session-factory>

Java Hibernate Schema Update does nothing

I am working with Hibernate on Java with a MySQL database. If I set hbm2ddl.auto to create`, all current tables are dropped and recreated correctly, but if I set it to "update" it does nothing to the database despite reporting the following line to the console:
INFO: HHH000228: Running hbm2ddl schema update
For reference, the code I am using to set up the database is:
final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
.configure()
.build();
While my cfg.xml file looks like:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://127.0.0.1:3306/testdatabase</property>
<property name="connection.username">xxxxxxxx</property>
<property name="connection.password">xxxxxxxx</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
<!-- Names the annotated entity class -->
<mapping class="com.test.case.Example"/>
</session-factory>
</hibernate-configuration>
Obviously since the create is working, I see no need to show my annotated class.
Edit:
The changes I expect to happen are basically to correct the database column types to the correct ones. Before running the update I change the column types in MySql to something different from the annotated schema but on update it's not correcting it as would be expected. In contrast when I dropped the table altogether the update did work, it would seem update is not as fully featured as expected?
Service registry requires some properties from the configuration. And because you are using non-standard name/location of the hibernate configuration file
final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
.configure("cfg.xml")
.build();

Re-establishing a db connection after a network failure - Hibernate

Hello everyone,
I am using hibernate ORM and oracle database. My cfg file has following properties:
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="connection.url">jdbc:oracle:thin:#url</property>
<property name="connection.username">username</property>
<property name="connection.password">pasword</property>
<property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.timeout">300</property>
<property name="hibernate.c3p0.max_statements">50</property>
<property name="hibernate.c3p0.idle_test_period">3000</property>
<property name="hibernate.c3p0.acquire_increment">3</property>
Everything works fine, but when I run the application and if I unplug network cable and plug it agian my db queries fail. It gives me the error
java.sql.SQLException: Io exception: Connection reset by peer: socket write error
Is there any way to re establish the connection?
You need to configure your database connection pool - not hibernate.Try setting idleConnectionTestPeriod and an appropriate preferredTestQuery, e.g., select 1 from dual.
See How To Configure The C3P0 ConnectionPool for more information. You'll get the most control if you create a c3p0.properties file in WEB-INF/classes but you need to make sure not to override those properties in your hibernate.cfg.xml.
Well I had written c3p0-config.xml like
<c3p0-config>
<default-config>
<!-- Configuring Connection Testing -->
<!-- property name="automaticTestTable">TEST_EMS_HIBERNATE_CONN</property -->
<property name="checkoutTimeout">0</property>
<property name="testConnectionOnCheckout">true</property>
<property name="testConnectionOnCheckin">false</property>
<property name="preferredTestQuery">SELECT 1 from dual</property>
<!-- Configuring Recovery From Database Outages -->
<property name="acquireRetryAttempts">0</property>
<property name="acquireRetryDelay">1000</property>
<property name="breakAfterAcquireFailure">false</property>
<!-- Configuring to Debug and Workaround Broken Client Apps -->
<property name="unreturnedConnectionTimeout">1800</property>
<property name="debugUnreturnedConnectionStackTraces">true</property>
</default-config>
and the system properties like:
C3P0_SYS_PROPS="-Dcom.mchange.v2.c3p0.cfg.xml=<FILE-PATH>/c3p0-config.xml -Dcom.mchange.v2.log.MLog=com.mchange.v2.log.FallbackMLog -Dcom.mchange.v2.log.FallbackMLog.DE
FAULT_CUTOFF_LEVEL=WARNING"
As I see, you have specified when test connection, but have not specified how to test them. Read it http://www.mchange.com/projects/c3p0/index.html#configuring_connection_testing . I guess you should just add preferredTestQuery, usually it's something like SELECT 1 FROM DUAL.
Also read here Something wrong with Hibernate DB connection pooler c3p0

Categories