LocalDate MySQL persistence comes back the date before - mysql

I have seen this question posted a few times on StackOverflow, and it has been with mostly Spring Boot apps with Spring Boot Configuration. I've followed all the steps, and I still have this issue. If I can't get this resolved soon, I will have to go back to the old java.util.Date in order to persist my data to the database ... at least it worked without issues. So, I have a Spring 5.1.2.Release app, with Hibernate 5.4.0.Final, the hibernate-java8 dependency, and the latest MySQL Connector 8.0.13.
I understand from previous posts and other articles on the Net that if the database is set for UTC, but the App is running in another timezone, in my case GMT-5 for EST, then this problem might pop up.
So, here are the technical details:
My MySQL connection looks like:
hibernate.connection.url=jdbc:mysql://localhost:3306/my_db?
serverTimezone=UTC&useLegacyDatetimeCode=false&useTimezone=true
The connection string, is used in the applicationContext.xml:
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>${hibernate.connection.driver.class}</value>
</property>
<property name="url">
<value>${hibernate.connection.url}</value>
</property>
<property name="username">
<value>${hibernate.connection.username}</value>
</property>
<property name="password">
<value>${hibernate.connection.password}</value>
</property>
</bean>
My Hibernate properties in my applicationContext.xml look like:
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.cglib.use_reflection_optimizer">${hibernate.cglib.use_reflection_optimizer}</prop>
<prop key="useUnicode">true</prop>
<prop key="useLegacyDatetimeCode">false</prop>
<prop key="serverTimezone">UTC</prop>
<prop key="useTimezone">true</prop>
<prop key="hibernate.jdbc.time_zone">UTC</prop>
</props>
</property>
My Maven dependencies are:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.4.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-java8</artifactId>
<version>5.4.0.Final</version>
</dependency>
My Entity Code is simple:
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "transaction_id")
private long txId;
#Column(name = "transaction_date")
private LocalDate txDate;
I save my code to the database like this:
#Override
public TxEntity create(TxEntity txEntity)
{
this.sessionFactory.getCurrentSession().save(txEntity);
this.sessionFactory.getCurrentSession().flush();
this.sessionFactory.getCurrentSession().refresh(txEntity);
return txEntity;
}
The database has "transaction_date" as a DATE field in MySQL.
My Unit Test shows that I can create a new record, and I have set the date as follows:
LocalDate today = LocalDate.now();
I persist the record, and when I test:
assertEquals(today, myRecord.getTransactionDate());
this fails, because I get the previous date.
I thought that if I used the latest versions of Hibernate and the Hibernate-java8 I would be fine, but that's not the case. I thought if I pulled in the latest JPA2.2 that would work, but it's not. So, I think I am doing everything right, and I still have an issue.
So, if there is anything you need to see, let me know and I can add it. I think I am doing everything right, but if there is anything off I need to fix, please let me know. And of course, I'll keep looking at this myself.

If you don't want to touch your Java project or connection strings to solve this issue you can configure the MySQL timezone directly. On my computer the JVM timezone was correct (America/Sao_Paulo), so changing it to UTC in order to solve this conflict with MySQL was a no go.
The problem I had was just at the MySQL timezone configuration. Since I run MySQL on a container it got a wrong default timezone. The fix was to pass the --default-time-zone=America/Sao_Paulo to the MySQL container configuration, which fixed this issue. Now both MySQL and JVM got the same timezone.

For me, after some debugging for some time, I noticed Mysql timezone was UTC, but my default jvm timezone which can be seen by:
public class DefaultTimeZone {
public static void main(String[] args) {
System.out.println(java.util.TimeZone.getDefault().getID());
}
}
was America/Montreal so in updated my ide (IntellJ) settings to pass -Duser.timezone=UTC as a parameter when starting the application. (Of course there are so many other ways to do this, but in my case this was enough)

Related

Hibernate Dialect for MySQL8

I am getting below error in Spring Application with Hibernate. I have just upgraded the database mysql version from 5.6 to 8.0.
The Error is:
nested exception is org.hibernate.HibernateException: Dialect class not found: org.hibernate.dialect.MySQL8Dialect
In my build.gredle file I have included the following:
dependencies {
compile group: 'mysql', name: 'mysql-connector-java', version: '8.0.11'
}
And in my applicationContext.xml file I have included the following:
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.jdbc.batch_size">20</prop>
</props>
</property>
In my lib folder I have the connector also "mysql-connector-java-8.0.11.jar".
I don't understand why the dialect is still missing. Please help. :)
I was using Hibernate v-3.3.0 which actually dose not support the specified dialect. The reference link of the specified hibernate version is (https://javadoc.io/doc/org.hibernate/hibernate-core/3.3.0.CR1/index.html). Thanks to M. Deinum(https://stackoverflow.com/users/2696260/m-deinum) for helping me finding the issue.

Connecting database with hibernate

I know thats a known problem and i made my research but still couldnt find a proper answer and what to do, so my last hope is here. The problem is, when i use phpAdmin i can connect and create my tables in m database. But when i run hibernates connection wizard, after entering the connection properties, if i press the test connection it gives me this error :
"Timeout expired. IDE unable to establish connection. Check your proxy settings or try again later. The server may be unavailable at the moment.   You may also want to make sure that your firewall is not blocking network traffic."
My hibernate.cfg.xml looks like this
<?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.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://127.11.83.2:3306</property>
<property name="hibernate.connection.username">admin1s6nbcM</property>
<property name="hibernate.connection.password">*******</property>
</session-factory>
</hibernate-configuration>
I m suspecting that there is something wrong with MySQL Java Connector library ;
dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.30</version>
</dependency>
because i get this warning when i build my application:
Some problems were encountered while building the effective model for cardsystelefonbuch:cardsystelefonbuch:war:1.0
'dependencies.dependency.(groupId:artifactId:type:classifier)' must be unique: mysql:mysql-connector-java:jar -> version 5.1.25 vs 5.1.30 # line 83, column 13
It is highly recommended to fix these problems because they threaten the stability of your build.
For this reason, future Maven versions might no longer support building such malformed projects.
Any ideas would be greatly appreciated !

Using MySQL database for authentication in Ja-sig CAS

I'm trying to hook my Ja-sig CAS server (v3.5 running on Tomcat7) up to a MySQL database for user authentication. I basically have a table 'users' in the database storing username/password pairs that I want CAS to check against. However, I'm having difficulty even getting my current configuration to deploy.
This is an excerpt from pom.xml as it relates to database connectivity:
<dependency>
<groupId>org.jasig.cas</groupId>
<artifactId>cas-server-support-jdbc</artifactId>
<version>${cas.version}</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.22-bin</version>
<scope>provided</scope>
</dependency>
And here is where I try to setup the database connection in WEB-INF/deployerConfigContext.xml:
<bean
class="org.jasig.cas.adaptors.jdbc.SearchModeSearchDatabaseAuthenticationHandler">
<property name="tableUsers">
<value>users</value>
</property>
<property name="fieldUser">
<value>username</value>
</property>
<property name="fieldPassword">
<value>password</value>
</property>
<property name="passwordEncoder">
<bean
class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder">
<constructor-arg value="MD5" />
</bean>
</property>
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="datasource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost:3306/cas_db</value>
</property>
<property name="username">
<value>cas_server</value>
</property>
<property name="password">
<value>pass</value>
</property>
</bean>
It builds perfectly fine with Maven, but when I try to deploy it with Tomcat it doesn't work. I haven't been able to find anything particularly informative in any of the tomcat logs. I'm wondering if there might be a problem with 'commons-dbcp', since when I comment that out and use a simple authentication handler in deployerConfigContext.xml, I'm able to deploy.
There seems to be little/poor documentation of this from my current web research. If anyone has any good resources they could recommend as well, it would be greatly appreciated.
I finally found a trace of errors in the tomcat log localhost.YYYY-MM-DD.log. As it turns out, I needed to add commons-pool:
<dependency>
<groupId>commons-pool</groupId>
<artifactId>commons-pool</artifactId>
<version>1.6</version>
<scope>provided</scope>
</dependency>
which commons-dbcp is dependent upon. Installing this with Maven did away with the missing class exception I was getting.
My next problem was that I had mistakenly defined my datasource bean in the list of authenticationHandlers in deployerConfigContext.xml, which led to a type conversion exception. Moving the bean out of the list tag did the trick.
On one of the official guides for CAS + JDBC Authentication (https://wiki.jasig.org/display/CASUM/Using+JDBC+for+Authentication), they comment on that:
Note: It is recommended commons-dbcp 1.2.1 is used with MySQL instead of the newer version. I found that new version (1.2.2) will cause a Socket write error in MySQL, after your CAS is idle for more that 8 hours, which is the time that MySQL will clean up all idle connections.
Your problem might be related to the version of the commons-dbcp. In my case, I have a configuration similar to yours with the difference on the commons-dbcp version, I'm using 1.4 (no problems)

resume for XID raised 0: unknown

I am using Spring 3.0.5, Hibernate 3.6.7, Atomikos TransactionEssentials 3.7.0 and MySQL 5.5
I recently faced the problem, that connections in my connectionpool timedout after 8 hours and were reset by the server causing a message "resume for XID '???' raised 0: unknown
Here is my datasource configuration:
<bean id="myDataSource"
class="com.atomikos.jdbc.AtomikosDataSourceBean"
init-method="init"
destroy-method="close"
depends-on="myConfigurer">
<property name="uniqueResourceName" value="myPUDataSource" />
<property name="xaDataSourceClassName" value="$CONF{database.XAdriver}" />
<property name="poolSize" value="10" />
<property name="xaProperties">
<props>
<prop key="user">$CONF{database.user}</prop>
<prop key="password">$CONF{database.password}</prop>
<prop key="URL">$CONF{database.url}</prop>
<prop key="pinGlobalTxToPhysicalConnection">true</prop>
<prop key="autoReconnect">true</prop>
</props>
</property>
</bean>
As I was investigating I found out that the option autoReconnect=true only reconnects my faulted connection after a delay of 2 seconds (which is configurabe I think).
Browsing the web I found solutions suggesting to increase wait_timeout in the MySQL-Server, which I think is not a real solution.
The application should be able to handle dead connections and reconnect automatically, because there may be other issues causing a connection loss, too.
(And I don't want to make any directives to Servers whatever kind the application uses).
At last I found a good solution for this, which I will post as answer to help people facing the same or similar problems.
By inserting the line:
<property name="testQuery" value="SELECT 1"/>
on the data source's configuration, it seems the connection is tested before use and reconnected if it's dead.
I tried it with wait_timeout=60 and even with a restart of the MySQL-Server while my application was running...
Result: no more Exceptions and Errors!

Hibernate question

I getting an error when running my program. the error is: org.hibernate.HibernateException: JDBC Driver class not found: com.mysql.jdbc.Driver.
The driver is there...I am not sure what it causing this. Any suggestions?
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/registrar</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<mapping resource="com/ths/entity/Course.hbm.xml"/>
<mapping resource="com/ths/entity/Student.hbm.xml"/>
<mapping resource="com/ths/entity/Enrollment.hbm.xml"/>
</session-factory>
</hibernate-configuration>
The driver is there...I am not sure what it causing this.
The driver is not there. The error is simple: the Java VM couldn't find your driver. So, double-check the classpath. If you are deploying a web-application, make sure your driver is in the server's lib, and not in WEB-INF/lib.
You may have that jar in project but class loader is unable to find that as class loader does not check each and every folder of project. If it is a web application then you need to put jar file in WEB-INF/LIB.
If it is a standalone application then you need to add jar file in build path.
you can check class path during run time to see whether folder (where jar exist) is considered in class path or not.
I am not sure what was causing this. I was trying this on my work computer. I tried it at home and it worked fine. Must just be a setting.