Datasource configuring in Hibernate 5, Tomcat 8 - java

Need some clarification and helps. Especially appreciate describing general concepts or link where they are described.
So, on the hibernate website I have read the next one:
For use inside an application server, you should almost always
configure Hibernate to obtain connections from an application server
javax.sql.Datasource registered in JNDI. You will need to set at least
one of the following properties:
And I have a few question because at the moment I am really confused about all of that stuff with DataSource, DataDriver, Tomcat and Hibernate in general.
Does configuring Datasource and binding SessionFactory to the JNDI
is the same process?
If no, for what we use DataSource and for why we need to bind SessionFactory to JNDI (in general)?
Am I understood right? If we configure DataSource in hibernate.cfg.xml file we don't need to configure it in {tomcat}/conf/server.xml or {tomcat}/conf/context.xml?
What is hibernate.jndi.url? Does it is the same as hibernate.connection.url?
What is hibernate.connection.datasource? In docs I read that it is "datasource JNDI name", so if I understood right it can be any name?
From Hibernate docs I read that setting at least one of the properties hibernate.connection.datasource, hibernate.jndi.url, hibernate.jndi.class, hibernate.connection.username, hibernate.connection.password makes my app use javax.sql.Datasource registered in JNDI. So does the next conf already configured to use DataSource?
How to check that DataSource used and configured fine?
My hibernate.cfg.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.use_sql_comments">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.generate_statistics">true</property>
<!--http://stackoverflow.com/questions/2067526/hibernate-connection-pool-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!--For use inside an application server, you should almost always configure Hibernate to obtain connections from an application server javax.sql.Datasource registered in JNDI. You will need to set at least one of the following properties:-->
<!--hibernate.connection.datasource,hibernate.jndi.url,hibernate.jndi.class,hibernate.connection.username,hibernate.connection.password-->
<!--Datasource config-->
<property name="hibernate.connection.datasource">jdbc:mysql://localhost/easywordweb</property>
<!--<property name="hibernate.jndi.url">??????? what is it</property>-->
<!--/Datasource config-->
<!--*****************************************************************-->
<!--C3P0 config-->
<!--Hibernate will obtain and pool connections using java.sql.DriverManager if you set the 5 following properties -->
<!--hibernate.connection.driver_class,hibernate.connection.url,hibernate.connection.username,hibernate.connection.password,hibernate.connection.pool_size-->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost/easywordweb</property>
<property name="hibernate.connection.username">username</property>
<property name="hibernate.connection.password">password</property>
<!--We can use a third party pool for best performance and stability, for example c3p0. Just replace the hibernate.connection.pool_size property with connection pool specific settings. This will turn off Hibernate's internal pool. For example, you might like to use c3p0. -->
<!--<property name="hibernate.connection.pool_size">140</property>-->
<property name="hibernate.c3p0.max_size">140</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.acquire_increment">5</property>
<!--max to cache-->
<property name="hibernate.c3p0.max_statements">50</property>
<!--The seconds a Connection can remain pooled but unused before being discarded. Zero means idle connections never expire. Hibernate default: 0-->
<property name="hibernate.c3p0.timeout">21600</property>
<!--for test, change futher-->
<property name="hibernate.c3p0.preferredTestQuery">SELECT 1;</property>
<!--at every connection checkin to verify that the connection is valid-->
<property name="hibernate.c3p0.testConnectionOnCheckout">true</property>
<!--at every connection checkout to verify that the connection is valid-->
<property name="hibernate.c3p0.testConnectionOnCheckin">true</property>
<!--/for test, change futher-->
<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<!--/C3P0 config-->
<!--*****************************************************************-->
<property name="hibernate.c3p0.validate">true</property>
<!--c3p0 will test all idle, pooled but unchecked-out connections, every this number of seconds-->
<property name="hibernate.c3p0.idle_test_period">21000</property>
<property name="hibernate.jdbc.batch_size">20</property>
<!--Number rows to be returned if no setted-->
<property name="hibernate.jdbc.fetch_size">20</property>
<property name="hibernate.jdbc.use_get_generated_keys">true</property>
<property name="hibernate.temp.use_jdbc_metadata_defaults">false</property>
<!--FIXING: Table "...".hibernate_sequence table not found.-->
<property name="hibernate.id.new_generator_mappings">false</property>
</session-factory>
</hibernate-configuration>
Thank's everyone in advance.

In the config you have posted you are initializing the connection pool within your application.
An alternative is to delegate the creation of the database pool to your app/web server and expose it as a JNDI resource. Your application need then only specify the name of the JNDI datasource to obtain a connection.
Doing this in Tomcat is documented here:
https://tomcat.apache.org/tomcat-6.0-doc/jndi-datasource-examples-howto.html
Your hibernate.cfg.xml then looks like:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.use_sql_comments">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.generate_statistics">true</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- The Server configured JNDI datasource -->
<property name="hibernate.connection.datasource">java:comp/env/jdbc/MyLocalDB</property>
<property name="hibernate.jdbc.batch_size">20</property>
<!--Number rows to be returned if no setted-->
<property name="hibernate.jdbc.fetch_size">20</property>
<property name="hibernate.jdbc.use_get_generated_keys">true</property>
<property name="hibernate.temp.use_jdbc_metadata_defaults">false</property>
<!--FIXING: Table "...".hibernate_sequence table not found.-->
<property name="hibernate.id.new_generator_mappings">false</property>
</session-factory>
</hibernate-configuration>

Related

mysql utf-8 returns gibberish from one machine

I have mysql DB with UTF-8 and application written in java with hibernate. When I run the application in eclipse everything is fine. But in production which is on a different machine the values returned from DB are corrupted.
I print the values to log (immediately after getting them) and I clearly see that the values I get from DB are corrupted in production.
The DB itself is the same DB for both environments. The values are stored fine.
Any ideas what can be the reason for this?
UPDATE:
I forgot to say that it happens sometimes. I think that in 50% of the times it works fine.
UPDATE 2:
Here is the hibernate.cfg.xml:
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://myDB:3306/myApp?autoReconnect=true&useUnicode=true&createDatabaseIfNotExist=true&characterEncoding=utf-8</property>
<property name="hibernate.connection.username">username</property>
<property name="hibernate.connection.password">password</property>
<!-- <property name="hibernate.connection.pool_size">10</property> -->
<property name="hibernate.connection.isolation">2</property>
<property name="show_sql">true</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.connection.provider_class">com.zaxxer.hikari.hibernate.HikariConnectionProvider</property>
<property name="hibernate.hikari.minimumIdle">5</property>
<property name="hibernate.hikari.maximumPoolSize">10</property>
<property name="hibernate.hikari.idleTimeout">30000</property>
<mapping class="someclass1"/>
<mapping class="someclass2"/>
<mapping class="someclass3"/>
<mapping class="someclass4"/>
</session-factory>
</hibernate-configuration>
Reference URL: https://docs.jboss.org/exojcr/1.12.13-GA/developer/en-US/html/ch-db-configuration-hibernate.html
Please verify the datasource configuration in your production environment whether the attributes - useUniCode and characterEncoding are set properly. Example:
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/exodb?relaxAutoCommit=true&amp;autoReconnect=true&amp;useUnicode=true&amp;characterEncoding=utf8"/>

how to get rid of c3p0 deadlock error

I'm using hibernate 4.3.6 with c3p0 0.9.2.1 and I'm getting the following error very frequently:
ThreadPoolAsynchronousRunner:778 - com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector#9abc33e -- Running DeadlockDetector[Exiting. No pending tasks.]
This slows down the server and I have no idea what's causing it and how to get rig of it.
This is my hibernate.config file:
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://ip:port/app?autoReconnect=true&useUnicode=true&createDatabaseIfNotExist=true&characterEncoding=utf-8</property>
<property name="hibernate.connection.username">username</property>
<property name="hibernate.connection.password">password</property>
<property name="hibernate.connection.isolation">2</property>
<property name="show_sql">true</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">100</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>
<mapping class="server.c1"/>
<mapping class="server.c2"/>
<mapping class="server.c3"/>
<mapping class="server.c4"/>
<mapping class="server.c5"/>
</session-factory>
</hibernate-configuration>
In addition I also have a c3p0.properties file:
c3p0.testConnectionOnCheckout=true
c3p0.privilegeSpawnedThreads=true
c3p0.contextClassLoaderSource=library
There are a lot of questions about it but I couldn't find a concrete solution.
I had a similar problem with c3p0. My final solution was use this connection pool https://github.com/brettwooldridge/HikariCP
If you are still using c3p0, the following steps are likely to resolve this issue:
Update to the latest c3p0 (now 0.9.5.2).
Set the following config parameter:
c3p0.statementCacheNumDeferredCloseThreads=1
See the docs.
Update: Oh, wait. I responded too quickly. Sorry!
You are not actually seeing deadlocks, you are just seeing messages that the deadlock detector is running. The message that you are seeing is not an error at all, just a notification that gets logged at TRACE / DEBUG / FINEST (depending which logging library you use).
You should configure your logging so that loggers prefixed com.mchange log at INFO. That's it.

Hibernate configuration error while reading schema

Hey stackoverflow,
I tried to add a Hibernate configuration to my workspace in order to reverse engineer my database.
When I am opening the database point in the 'Hibernate Configurations' view, i get a Reading schema error: null with the following exception:
java.lang.NullPointerException
at org.hibernate.eclipse.console.workbench.LazyDatabaseSchemaWorkbenchAdapter$1.compare(LazyDatabaseSchemaWorkbenchAdapter.java:76)
at java.util.TimSort.countRunAndMakeAscending(Unknown Source)
at java.util.TimSort.sort(Unknown Source)
at java.util.Arrays.sort(Unknown Source)
at org.hibernate.eclipse.console.workbench.BasicWorkbenchAdapter.toArray(BasicWorkbenchAdapter.java:75)
at org.hibernate.eclipse.console.workbench.LazyDatabaseSchemaWorkbenchAdapter.getChildren(LazyDatabaseSchemaWorkbenchAdapter.java:74)
at org.hibernate.eclipse.console.workbench.BasicWorkbenchAdapter.fetchDeferredChildren(BasicWorkbenchAdapter.java:104)
at org.eclipse.ui.progress.DeferredTreeContentManager$1.run(DeferredTreeContentManager.java:238)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)
Has someone experienced this before?
I am running a fresh installation of Eclipse Luna / Newest JBoss Tools and trying to connect to a PostgreSQL 9.3 DB.
Thank you in advance
EDIT:
My hibernate.cfg.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
<property name="hibernate.connection.password">******</property>
<property name="hibernate.connection.url">jdbc:postgresql://10.244.7.77:5432/netview</property>
<property name="hibernate.connection.username">admin</property>
<property name="hibernate.default_schema">public</property>
</session-factory>
</hibernate-configuration>
EDIT 2:
I just realized, if i add a default schema <property name="hibernate.default_schema"> it works, but just for this schema.
EDIT 3:
It works with an old version of Hibernate tools (3.6.0.M1-v20120827-0757-H1125). Now i am confused.
Try out this config:
<!-- Database connection settings -->
org.postgresql.Driver
jdbc:postgresql://host:port/database
postgres
password
1
org.hibernate.dialect.PostgreSQLDialect
thread
org.hibernate.cache.internal.NoCacheProvider
true
Try out this config:
<session-factory>
<!-- Database connection settings -->
<property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
<property name="hibernate.connection.url">jdbc:postgresql://host:port/database</property>
<property name="hibernate.connection.username">postgres</property>
<property name="hibernate.connection.password">password</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</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>
</session-factory>
So i found out that it might be a bug in JBoss Tools. So I opened a ticket: https://issues.jboss.org/plugins/servlet/mobile#issue/JBIDE-19830

Hibernate auto create database

I have a Java EE Hibernate project, and I'm using MySQL as a database.
I want that when I first time run the project, it will create the database automatically.
This is my hibernate.cnf.xml:
<?xml version='1.0' encoding='utf-8' ?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd" >
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost/InternetProject</property>
<property name="connection.username">root</property>
<property name="connection.password"></property>
<property name="connection.pool_size">10</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="show_sql">true</property>
<mapping class="entities.Business" />
<mapping class="entities.Coupon" />
<mapping class="entities.User" />
<mapping class="entities.LastLogin" />
</session-factory>
</hibernate-configuration>
When I first time run this project on another computer, how can I make the database InternetProject to be created?
According to the config file, it might already do it and I'm not aware to it.
Thanks in advance.
<property name="hibernate.hbm2ddl.auto">create</property>
will create tables. But it will not create database. Change the connection url to generate the database.
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost/InternetProject?createDatabaseIfNotExist=true</property>
<property name="connection.username">root</property>
<property name="connection.password"></property>
<property name="connection.pool_size">10</property>
Update : character encoding when creating database
<property name="connection.url">
jdbc:mysql://localhost/InternetProject?createDatabaseIfNotExist=true&useUnicode=yes&characterEncoding=UTF-8
</property>
<property name="hibernate.hbm2ddl.auto">create</property>
will do
Hibernate will not create the database for you, only the tables. To create the database you need to tell MySQL to create it if it does'nt already exist by adding a parameter to the URL. E.g.:
jdbc:mysql://db:3306/mydatabase?createDatabaseIfNotExist=true
There are multiple option for auto property.
create - It creates new tables corresponding mapping or annotation. It drops existing tables and data.
update - It keeps existing data and tables. It updates schema. here we have to take care contrants.
create-drop - It is same like create but once session gets closed it drops everything.
validate - it validates or matches schema with map or annotation. It's valid for Production environment.
<!-- create create-drop validate update -->
<property name="hbm2ddl.auto">update</property>
I hope it helps.

how to configure hibernate config file for sql server

Here is the config file for MySQL:
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">org.gjt.mm.mysql.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost/test</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">zgy01</property>
<property name="hibernate.connection.pool_size">100</property>
<property name="show_sql">false</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Mapping files -->
<mapping resource="model.hbm.xml"/>
</session-factory>
</hibernate-configuration>
What to specify for SQL Server 2005? I did it like this:
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">org.gjt.mm.mysql.Driver</property>
<property name="hibernate.connection.url">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
<property name="hibernate.connection.username">sa</property>
<property name="hibernate.connection.password">lal</property>
<property name="dialect">org.hibernate.dialect.SQLServerDialect</property>
<property name="hibernate.connection.pool_size">100</property>
<property name="show_sql">false</property>
<!-- Mapping files -->
<mapping resource="model.hbm.xml"/>
</session-factory>
</hibernate-configuration>
My question more precisely is how to specify the database that I have to connect to?
In MySQL I used to do like this:
<property name="hibernate.connection.url">jdbc:mysql://localhost/test</property>
Properties that are database specific are:
hibernate.connection.driver_class: JDBC driver class
hibernate.connection.url: JDBC URL
hibernate.connection.username: database user
hibernate.connection.password: database password
hibernate.dialect: The class name of a Hibernate org.hibernate.dialect.Dialect which allows Hibernate to generate SQL optimized for a particular relational database.
To change the database, you must:
Provide an appropriate JDBC driver for the database on the class path,
Change the JDBC properties (driver, url, user, password)
Change the Dialect used by Hibernate to talk to the database
There are two drivers to connect to SQL Server; the open source jTDS and the Microsoft one. The driver class and the JDBC URL depend on which one you use.
With the jTDS driver
The driver class name is net.sourceforge.jtds.jdbc.Driver.
The URL format for sqlserver is:
jdbc:jtds:sqlserver://<server>[:<port>][/<database>][;<property>=<value>[;...]]
So the Hibernate configuration would look like (note that you can skip the hibernate. prefix in the properties):
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">net.sourceforge.jtds.jdbc.Driver</property>
<property name="connection.url">jdbc:jtds:sqlserver://<server>[:<port>][/<database>]</property>
<property name="connection.username">sa</property>
<property name="connection.password">lal</property>
<property name="dialect">org.hibernate.dialect.SQLServerDialect</property>
...
</session-factory>
</hibernate-configuration>
With Microsoft SQL Server JDBC 3.0:
The driver class name is com.microsoft.sqlserver.jdbc.SQLServerDriver.
The URL format is:
jdbc:sqlserver://[serverName[\instanceName][:portNumber]][;property=value[;property=value]]
So the Hibernate configuration would look like:
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
<property name="connection.url">jdbc:sqlserver://[serverName[\instanceName][:portNumber]];databaseName=<databaseName></property>
<property name="connection.username">sa</property>
<property name="connection.password">lal</property>
<property name="dialect">org.hibernate.dialect.SQLServerDialect</property>
...
</session-factory>
</hibernate-configuration>
References
Hibernate Core Reference Documentation
3.3. JDBC connections
3.4. Optional configuration properties
jTDS Documentation
Microsoft SQL Server JDBC Driver 3.0 Documentation
Microsoft SQL Server JDBC Driver 2.0
Support Matrix for Microsoft SQL Server JDBC Driver
The connection URL should look like this for SQL Server:
jdbc:sqlserver://serverName[\instanceName][:port][;databaseName=your_db_name]
Examples:
jdbc:sqlserver://localhost
jdbc:sqlserver://127.0.0.1\INGESQL:1433;databaseName=datatest
...
We also need to mention default schema for SQSERVER: dbo
<property name="hibernate.default_schema">dbo</property>
Tested with hibernate 4
Don't forget to enable tcp/ip connections in SQL SERVER Configuration tools
Finally this is for Hibernate 5 in Tomcat.
Compiled all the answers from the above and added my tips which works like a charm for Hibernate 5 and SQL Server 2014.
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">
org.hibernate.dialect.SQLServerDialect
</property>
<property name="hibernate.connection.driver_class">
com.microsoft.sqlserver.jdbc.SQLServerDriver
</property>
<property name="hibernate.connection.url">
jdbc:sqlserver://localhost\ServerInstanceOrServerName:1433;databaseName=DATABASE_NAME
</property>
<property name="hibernate.default_schema">theSchemaNameUsuallydbo</property>
<property name="hibernate.connection.username">
YourUsername
</property>
<property name="hibernate.connection.password">
YourPasswordForMSSQL
</property>
Keep the jar files under web-inf lib incase you included jar and it is not able to identify .
It worked in my case where everything was ok but it was not able to load the driver class.

Categories