Atomikos with MySQL JTA not working properly - mysql

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>

Related

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

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/

Customizing response code on uncaught exception in Roo

I have a Roo-based application.
If an exception got thrown from my controller, my application will render a stack trace to the end user, but the response will have the status code of 200.
How can I customize this so that any uncaught exception will result in a response with code 500?
In your webmvc-config.xml set defaultStatusCode property on org.springframework.web.servlet.handler.SimpleMappingExceptionResolver.
Example:
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver" p:defaultErrorView="uncaughtException">
<property name="exceptionMappings">
<props>
<prop key=".DataAccessException">dataAccessFailure</prop>
<prop key=".NoSuchRequestHandlingMethodException">resourceNotFound</prop>
<prop key=".TypeMismatchException">resourceNotFound</prop>
<prop key=".MissingServletRequestParameterException">resourceNotFound</prop>
</props>
</property>
<property name="defaultStatusCode">
<value>500</value>
</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.

c3p0 connection management problems

I'm using Spring 3.0.2, Hibernate 3.5.0 and c3p0 0.9.1.2 and I'm having a ton of errors when it comes down to retrieving connections and commiting transactions. Here's my configuration of c3p0:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driverClassName}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="properties">
<props>
<prop key="c3p0.acquireIncrement">5</prop>
<prop key="c3p0.maxIdleTime">30</prop>
<prop key="c3p0.idleConnectionTestPeriod">20</prop>
<prop key="c3p0.maxPoolSize">100</prop>
<prop key="c3p0.maxStatements">0</prop>
<prop key="c3p0.minPoolSize">1</prop>
<prop key="user">${jdbc.username}</prop>
<prop key="password">${jdbc.password}</prop>
</props>
</property>
</bean>
Up until recently I got this error pretty often:
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
Last packet sent to the server was 0 ms ago.
Recently I also get these:
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Connection.close() has already been called. Invalid operation in this state.
java.sql.SQLException: Connections could not be acquired from the underlying database!
Any suggestions?
That's probably because connections are being timed out. Checkout idle_test_period setting or use bonecp http://jolbox.com which has sensible defaults instead.