How to make AWS RDS MySql 5.6 case-insensitive? [duplicate] - mysql

This question already has an answer here:
Rename Amazon RDS table name to capital letter throws error
(1 answer)
Closed 6 years ago.
I am migrating my windows based Spring - Hibernate application to Amazon AWS.
I am getting issues with the Database since the table names in Amazon RDS starts with uppercase letter when hibernate creates them.
eg: userlogin_permissions in Windows local Mysql changes to Userlogin_permissions.
Due to this above error , my server cannot connect to the table and is not working.
I tried using
<prop key="org.hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
but is not helping.
The following is my xml structure :
<beans profile="awsSql">
<bean class="org.apache.tomcat.jdbc.pool.DataSource" id="dataSource">
<property name="url" value="jdbc:mysql://-----------"/>
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="username" value="#######"/>
<property name="password" value="##########"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="***-jpa"/>
<property name="dataSource" ref="dataSource"/>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="false"/>
<property name="generateDdl" value="true"/>
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect"/>
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="org.hibernate.envers.auditTablePrefix"></prop>
<prop key="org.hibernate.envers.auditTableSuffix">_AUD</prop>
<prop key="org.hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
<!--<prop key="org.hibernate.ejb.naming_strategy">org.hibernate.cfg.DefaultNamingStrategy</prop>-->
<!--<prop key="hibernate.cache.provider_class">org.hibernate.cache.SingletonEhCacheProvider</prop>-->
<!--<prop key="hibernate.cache.provider_configuration">/META-INF/cache/ehcache.xml</prop>-->
<prop key="hibernate.cache.use_second_level_cache">false</prop>
<prop key="hibernate.cache.use_query_cache">false</prop>
<!--<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>-->
<prop key="hibernate.generate_statistics">false</prop>
</props>
</property>
</bean>
Is there any way in which I can either make RDS use case-insensitive MYSQL , or make hibernate consistent in all OS.
I have already gone through the other related questions in here , but couldn't solve my problem.

You're looking to change the lower_case_table_names system variable and setting the value to 1.
How to change MySQL table names in Linux server to be case insensitive?
You'll have to create a new parameter group in RDS and then associate it to a mysql instance which will most likely require a restart. To see the instructions to do it via command-line that can be found below.
http://www.kulawik.de/blog/2011/02/lower_case_table_names/

Related

Hibernate changes database change from oracle to mysql

I am using Spring and Hibernate in my project. My database has changed from Oracle 10g to MySQL.
Can you please tell me what changes do I need to make in my Hibernate configuration?
Also are there any changes required in my Java code.
If you are using the hibernate.cfg.xml for your project to define the database property, then you need to change it to the below values for MySQL :-
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM
"http://www.hibernate.org/dtd/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://localhost:3306/{db.name}</property>
<property name="hibernate.connection.username">{db.name}</property>
<property name="hibernate.connection.password">{db.password}</property>
</session-factory>
</hibernate-configuration>
Also you need to include the mysql-connector jar in your pom.xml for example
<!--Mysql-Connector-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.36</version>
</dependency>
if you are not using the hibernate.cfg.xml and instead using some sessionFactory bean in your Spring ApplicationContext.xml. Then you need to change it to below :-
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="annotatedClasses">
</property>
<property name="hibernateProperties">
<props>
<!-- As of now not using hibernate.cfg.xml -->
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.validator.apply_to_ddl">false</prop>
<prop key="hibernate.validator.autoregister_listeners">false</prop>
<prop key="show_sql">true</prop>
<prop key="format_sql">true</prop>
</props>
</property>
</bean>
<bean id="dataSource"
class="org.apache.tomcat.dbcp.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.user}" />
<property name="password" value="${jdbc.pass}" />
</bean>
Please follow http://www.baeldung.com/hibernate-4-spring for complete example on how to setup hibernate with spring.

Atomikos with MySQL JTA not working properly

I'm currently working on Java application using Spring, Hibernate, etc. under Tomcat.
I tried to configure JTA using the Atomikos but It looks like I have a problem when flush is done :(
There's a lot of configuration so I'll put the major parts:
<bean id="dataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
<property name="xaDataSourceClassName">
<value>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</value>
</property>
</bean>
<bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" />
<bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.J2eeUserTransaction" />
<bean id="jtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" depends-on="userTransactionService,atomikosTransactionManager,atomikosUserTransaction">
<property name="transactionManager" ref="atomikosTransactionManager" />
<property name="userTransaction" ref="atomikosUserTransaction" />
<property name="allowCustomIsolationLevels" value="true"></property>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jtaTransactionManager" ref="jtaTransactionManager"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.use_sql_comments">false</prop>
<prop key="hibernate.current_session_context_class">jta</prop>
</props>
</property>
</bean>
While starting a Transaction using the #Transactional, I'm able to run queries but when saving via Hibernate getCurrentSession() I'm getting the following exception: (when commit it done)
org.springframework.transaction.UnexpectedRollbackException: JTA transaction unexpectedly rolled back (maybe due to a timeout); nested exception is javax.transaction.RollbackException: The transaction was set to rollback only
at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1024)
..
Caused by: com.atomikos.datasource.ResourceException: XA resource 'XADBMS': resume for XID '31302E38382E36382E32342E746D30303030313030303137:31302E38382E36382E32342E746D31' raised -5: invalid arguments
..
[11:36:30:534 (http-bio-8080-exec-3) org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorNonTrackingImpl$2.mapManagedFlushFailure(SynchronizationCallbackCoordinatorNonTrackingImpl.java:179)]
ERROR: HHH000346: Error during managed flush [XA resource 'XADBMS': resume for XID '31302E38382E36382E32342E746D30303030313030303139:31302E38382E36382E32342E746D31' raised -5: invalid arguments were given for the XA operation]
I think that i found the problem! it's related to Atomikos bug which is related to MySQL.
After adding the pinGlobalTxToPhysicalConnection=true parameter to the connection URL or as a parameter inside the com.atomikos.jdbc.AtomikosDataSourceBean Spring definition, It solved my problem.
<bean id="dataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean"
init-method="init" destroy-method="close">
...
<property name="xaProperties">
<props>
<prop key="pinGlobalTxToPhysicalConnection">true</prop>
</props>
</property>
</bean>

How connect multiply databases ( hsqldb, mysql ) with DB setting in separate files

Basically I want to decide with which of 2 databases project will run.
I have following hibernateContext.xml
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:database.properties</value>
</list>
</property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.user}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="com.blog.przem.entity" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
And database.properties file
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/pbdb
jdbc.user=root
jdbc.password=
What I'm trying to achieve is to add HSQLDB to my project (for development, testing) but for production I want to have MySQL DB.
I already seen some solutions:
in spring config file Can I use HSQLDB for junit testing cloning a mySQL database
in maven http://www.manydesigns.com/en/portofino/portofino3/tutorials/using-maven-profiles-and-resource-filtering
I wondering what is best approach, but I would like to keep databases settings in separate files.
Should I create database.properties2 file (with HSQL properties) and add propertyConfigurer2? And how to make dataSource bean to know which propertyConfigurer to use (I have feeling that I miss something)?
Maybe it should be done by maven?
What is professional approach to such problem (assuming that project finaly will use MySQL) - application should always use MySQL, and HSQLDB should be used only for running tests classes?
#Ralph answer works nice and as I was told it is good solution for bigger projects, and I have been given another solution how to resolve my problem so many databases can be set for project and tests files without creating additional applicationContext-db.xml ( however I don't know if having separate configuration xml's for tests is better than aproach presented below)
That code for slighty changed my hibernateContext.xml
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.user}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="com.blog.przem.entity" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${jdbc.hibernate.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.cache.use_second_level_cache">false</prop>
<prop key="hibernate.cache.use_query_cache">false</prop>
<prop key="hibernate.hbm2ddl.auto">create-drop</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.connection.autocommit">false</prop>
<prop key="hibernate.transaction.flush_before_completion">true</prop>
</props>
</property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
PropertyPlaceholderConfigurer was extracted (with removed id="propertyConfigurer") to new file proprtiesContext.xml
(of course was added to hibernateContext.xml)
<beans profile="default">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:msql_database.properties</value>
</list>
</property>
</bean>
</beans>
<beans profile="testing">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:hsql_database.properties</value>
</list>
</property>
</bean>
</beans>
Then I modified and added configuration files for both databases:
msql_database.propertie
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/pbdb
jdbc.user=root
jdbc.password=
jdbc.hibernate.dialect=org.hibernate.dialect.MySQLDialect
hsql_database.propertie
jdbc.driver=org.hsqldb.jdbcDriver
jdbc.url=jdbc:hsqldb:mem;shutdown=true
jdbc.user=sa
jdbc.password=
jdbc.hibernate.dialect=org.hibernate.dialect.HSQLDialect
Now if I run (in my case Tomcat) server it using "default" - nothing special - MYSQL database is used
But if I run server with parameter
-Dspring.profiles.active="testing"
It using given profile so my project using HSQLDB HOORAY
Additionally when I add specific profile in test class (just before class name declaration):
#ActiveProfiles("default")
public class UserServiceTest {
Specified database is used for testing
So I would recommend that the server provide the database connection via JNDI.
In additon you need to define the Database Dialact. Therefore I would recommend to use a Server Parameter.
For the test cases I would use an other database configruation file, that does not use jndi, but configure the database like you need it for your tests.
For example in Tomcat: Context.xml (global or better application specific context.xml)
<Resource name="jdbc/yourApp" type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/pbdb?useUnicode=true&characterEncoding=utf8"
auth="Container"
username="" password="geheim"
maxIdle="3" maxActive="15" maxWait="10000" logAbandoned="true" removeAbandoned="true"
removeAbandonedTimeout="60" validationQuery="select 1" />
<Parameter name="yourApp.database.dialect" value="mysql" override="false" />
Spring: applicationContext-db.xml in src\main\resources
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/yourApp"/>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="com.blog.przem.entity" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${yourApp.database.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
Now your are able to configure the application on every application server with an different database.
For Database-"integration" Tests based on Spring I would put an test specific applicationContext-db.xml without jndi and dialect property placeholder in src\test\resources (it "overrides" the normal one for the tests).
#See this answer for some additional information Spring Configuration - it describes an other way of how to name applicationContext-db.xml for the tests.

HSQLDialect to MySQL5InnoDBDialect, Hibernate

I've been using HSQLDialect as dialect for my database (MySQL, most of tables as InnoDB) on some projects and I never had any problem with Hibernate.
I encountered MySQLSyntaxErrorException when using setMaxResults() in a project using Spring 3.1.0 and Hibernate 3.6.9, and I still wonder where does that come from..
My XML config servlet :
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:mysql://localhost:3306/product" />
<property name="username" value="root" />
<property name="password" value="***************" />
</bean>
<bean id="mySessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="mappingResources">
<list>
<value>com/social/admin/beans/DevDebugLogs.hbm.xml</value>
<value>com/social/admin/beans/Users.hbm.xml</value>
...
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect"> org.hibernate.dialect.HSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
</props>
</property>
</bean>
<bean name="/logs.html" class="com.social.admin.controllers.DebugManagerAdmin">
<property name="sessionFactory" ref="mySessionFactory" />
</bean>
I tried to switch from HSQLDialect to MySQL5InnoDBDialect and it destroyed a big part of my database, dropping entries, deleting tables .... !!!!!!! X)
Can somebody help me ?
To avoid deleting tables and data, make sure you switch Hibernate in your configuration to update:
<prop key="hibernate.hbm2ddl.auto">update</prop>
This will help you to get rid of the problems with disappearing data.
Switching to MySQL5InnoDBDialect shouldn't cause any major problems. I have been using it for a very long time in every project of mine. The only thing that might happen is the fact, that some queries might not run exactly the same under different dialects, but you will be able to examine it at runtime or during tests.

About c3p0 and hibernate

I write a hibernate.cfg.xml file almost the same from hibernate books like:
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<property name="hibernate.connection.password">**</property>
<property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/db</property>
<property name="hibernate.connection.username">**</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.cache.use_second_level_cache">false</property>
<property name="hibernate.cache.use_query_cache">false</property>
<property name="c3p0.min_size">5</property>
<property name="c3p0.max_size">30</property>
<property name="c3p0.time_out">1800</property>
<property name="c3p0.max_statement">50</property>
<!--property name="show_sql">true</property-->
<property name="format_sql"> true</property>
But this seems actually c3p0 is not used. When I do test to establish 1000 sessions, it tries to establish 1000 connections.
Could anyone please give me some hint about this?
Thank you
Looking at your configuration file seems that you are missing one key property
<property name="connection.provider_class">
org.hibernate.connection.C3P0ConnectionProvider
</property>
Try setting this property and see if this turns things around for you or not.