Mybatis caching and concurrent modfications - mybatis

I am using mybatis 3.0.4 for a test against a mysql 5.5 database with mysql-connector JDBC driver, version 5.1.16.
The problem I am experiencing is that if I get a SqlSession via openSession() method and i retrieve data via a select from database, subsequent selects in same session are not aware of changes made (and committed) to database even if i call clearCache() on session. To concurrently modify database I am using Mysql command line client. Setting cacheEnabled as false in configuration file doesn't help too.
I enclose configuration file.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//ibatis.apache.org//DTD Config 3.0//EN"
"http://ibatis.apache.org/dtd/ibatis-3-config.dtd">
<configuration>
<settings>
<setting name="lazyLoadingEnabled" value="false"/>
<setting name="cacheEnabled" value="false"/>
</settings>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="poolMaximumIdleConnections" value="20"></property>
<property name="poolMaximumActiveConnections" value="80"></property>
<property name="poolMaximumCheckoutTime" value="600"></property>
<property name="poolTimeToWait" value="600"></property>
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/testdb"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mappers/TestMapper.xml" />
</mappers>
</configuration>

Ok, solved by myself. It was not a mybatis issue, it depended on Transaction isolation on JDBC driver, which was by default TRANSACTION_REPEATABLE_READ, I needed TRANSACTION_READ_COMMITTED instead. Solved with:
getSessionFactory().openSession(TransactionIsolationLevel.READ_COMMITTED);

Related

Encoding UTF-8 problem while JPA/hibernate execute sql-script with Intelli-J

Im developing a Jee webapp using JPA/Hibernate as ORM framework, PostgreSQL as db, and Tomcat as server.
When i start the app i want entitymanager to inject some data in my db.
I do that whith
<property name="javax.persistence.sql-load-script-source" value="META-INF/data.sql"/>
in persistence.xml
Everything works fine except that i get some bad encoding like "Ardèche" instead of "Ardèche".
My whole project is in utf-8, my database too.
I had encoding output problems in Intelli-j terminal with tomcat, that i managed to resolve using -Dfile.encoding=UTF-8 in Help | Edit Custom VM Options.
But my data in my db is still wrong, even if in Intelli-J output i get the good result.
If i execute the script straight into pgadmin there is no problem.
I tried everything i could find to solve that, but nothing worked.
I probably have conflict in the configuration now, cause i tried too many different stuff.
My persistence.xml
<properties>
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/DB" />
<property name="javax.persistence.jdbc.user" value="db" />
<property name="javax.persistence.jdbc.password" value="" />
<property name="hibernate.connection.useUnicode" value="true" />
<property name="hibernate.connection.characterEncoding" value="UTF-8" />
<property name="hibernate.connection.charSet" value="UTF-8"/>
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="create" />
<property name="javax.persistence.sql-load-script-source" value="META-INF/data.sql"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL95Dialect"/>
<property name="hibernate.connection.autocommit" value="true" />
</properties>
It's my first message on stackoverflow so i hope i did everything properly !
Thanks !
thanks for your answer, i just managed to fix it by adding <property name="hibernate.hbm2ddl.charset_name" value="UTF-8"/> to persistence.xml. I didn't check enough the hibernate doc !

How to specify character encoding for h2 in memory database scripts?

I have troubles with character encoding in my JPA test class.
In my h2 in memory database I have this insert query :
INSERT INTO MYTABLE (ID,FIELD1,FIELD2) VALUES (100,'ABC','Réclamation');
(please notice the "é" character in "Réclamation")
In my JUnit Test, I try to assert that the value of FIELD2 column is equal to "Réclamation" (which is the case as you can see)
But it fails with the following error :
org.junit.ComparisonFailure: expected:R[é]clamation but
was: R[�]clamation
I wonder if there is a way to specify character encoding in persistence.xml file (maybe ? or somewhere else)
Here is my persistence.xml test file :
<?xml version="1.0" encoding="UTF-8"?>
<persistence
version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="myTestPU">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>com.myproject.myclass1</class>
<class>com.myproject.myclass2</class>
<properties>
<property
name="javax.persistence.schema-generation.database.action"
value="none" />
<property
name="javax.persistence.sharedCache.mode"
value="ENABLE_SELECTIVE" />
<property
name="javax.persistence.jdbc.url"
value="jdbc:h2:mem:test;INIT=RUNSCRIPT FROM 'classpath:ddl/schema.sql'\;RUNSCRIPT FROM 'classpath:ddl/data.sql'" />
<property
name="javax.persistence.jdbc.driver"
value="org.h2.Driver" />
<property
name="hibernate.dialect"
value="org.hibernate.dialect.H2Dialect" />
<property
name="hibernate.show_sql"
value="true" />
<property
name="hibernate.format_sql"
value="true" />
</properties>
</persistence-unit>
</persistence>
I've already tried these solutions :
adding the following properties in persistence.xml test file :
<property
name="hibernate.connection.characterEncoding"
value="utf8" />
<property
name="hibernate.connection.useUnicode"
value="true" />
<property
name="hibernate.connection.charSet"
value="UTF-8" />
adding ?useUnicode=yes&characterEncoding=UTF-8 in my URL property
None of them worked for me...
NB : I don't use spring framework in my application
I had my insert queries in an import.sql file and those values were encoded incorrectly.
Adding the property
<property name="hibernate.hbm2ddl.charset_name" value="UTF-8" />
fixed it for me.
If you have an older version of hibernate (pre 5.2.3 apparently), maybe try the other solutions in this thread:
Hibernate/JPA import.sql utf8 characters corrupted

Issue with JPA in JBoss Fuse 6.2

I am trying to implement a JPA application in JBoss Fuse 6.2. The attached files are the pom.xml, blueprint.xml and persistence.xml. They are working fine in JBoss Fuse 6.1. But we are always getting the error "No providers available" in 6.2 and the deployment is going in "waiting" stage.
I believe the problem is with the "jpa" feature. In 6.2, when I do "features:info jpa", it shows hibernate's bundle as the jpa unit ( mvn:org.hibernate.javax.persistence/hibernate-jpa-2.1-api/1.0.0.Final), whereas in 6.1, it was the geronimo jpa bundle (mvn:org.apache.geronimo.specs/geronimo-jpa_2.0_spec/1.1). I believe that is causing OpenJPA to fail since OpenJPA is compliant with JPA 2.0 but not 2.1. Please guide on how to solve this problem. I have tried not to use the jpa feature and rather use the bundles of the jpa feature from 6.1 version but it did not help either.
pom.xml
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>fabric8-maven-plugin</artifactId>
<version>${fabric.version}</version>
<configuration>
<profile>org-profile</profile>
<parentProfiles>feature-cxf</parentProfiles>
<features>fabric-cxf swagger cxf-jaxrs transaction jndi jpa camel-spring spring-orm spring-jdbc
</features>
<featureRepos>
mvn:org.apache.cxf.karaf/apache-cxf/${version:cxf}/xml/features
mvn:org.apache.camel.karaf/apache-camel/${version:camel}/xml/features
</featureRepos>
<bundles>
mvn:mysql/mysql-connector-java/5.1.34
mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.commons-dbcp/1.4_3
mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.serp/1.14.1_1
mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.commons-collections/3.2.1_3
mvn:org.apache.openjpa/openjpa/2.3.0
</bundles>
</configuration>
</plugin>
blueprint.xml
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs"
xmlns:cxf="http://cxf.apache.org/blueprint/core"
xmlns:jpa="http://aries.apache.org/xmlns/jpa/v1.1.0"
xmlns:tx="http://aries.apache.org/xmlns/transactions/v1.0.0"
>
<jaxrs:server id="organizationService" address="/common">
<jaxrs:serviceBeans>
<ref component-id="organizationServiceBean"/>
</jaxrs:serviceBeans>
<jaxrs:features>
<bean class="org.apache.cxf.jaxrs.swagger.SwaggerFeature"/>
</jaxrs:features>
</jaxrs:server>
<cxf:bus>
<cxf:features>
<cxf:logging />
</cxf:features>
</cxf:bus>
<bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://127.0.0.1:3306/test"/>
<property name="username" value="user"/>
<property name="password" value="pwd"/>
</bean>
<service ref="dataSource" interface="javax.sql.DataSource">
<service-properties>
<entry key="osgi.jndi.service.name" value="jdbc/DataSource"/>
</service-properties>
</service>
<bean id="defOrganizationService" class="org.OrganizationDataServiceImpl">
<jpa:context unitname="PERSON"/>
<tx:transaction method="*" value="Required"/>
</bean>
<bean id="defOrgchartService" class="org.OrgchartDataServiceImpl">
<jpa:context unitname="PERSON"/>
<tx:transaction method="*" value="Required"/>
</bean>
<bean id="organizationServiceBean" class="org.OrganizationService">
<property name="organizationDataService" ref="defOrganizationService"/>
<property name="orgchartDataService" ref="defOrgchartService"/>
</bean>
</blueprint>
persistence.xml
<persistence-unit name="PERSON" transaction-type="JTA">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=jdbc/DataSource)</jta-data-source>
<!-- this is very important -->
<class>org.Person</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<!-- Schema update -->
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema"/>
<!-- Specify dialect -->
<property name="openjpa.jdbc.DBDictionary" value="mysql"/>
<property name="openjpa.Log" value="File=C:/install/jboss-fuse-6.1.0.redhat-379/data/log/org.apache.openjpa.log, DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE"/>
</properties>
</persistence-unit>
</persistence>

connecting to Oracle XE with myBatis using JDBC in Eclipse

I'm using Eclipse with Maven, in myBatis-config.xml I have the following codes. The H2 part of the code works as I can connect to H2 with my program and access the database. The Oracle part of my code doesn't work. I'm using ORACLE DATABASE XE 11.2, application express with a workspace: test, username: name, password: 123. When I run a testing class in Eclipse, I could pass the H2 tests, but when I run the same test using oracle instead, it gets an error. "Error selecting key or setting result to parameter object. Case: java.sql.SQLSyntaxErrorException: ORA-02289: sequence does not exist.
<environment id="H2">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:tcp://localhost:9096/sample/testDB" />
<property name="username" value="sa" />
<property name="password" value="123" />
</dataSource>
</environment>
<environment id="ORACLE">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="oracle.jdbc.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#localhost:1521:xe" />
<property name="username" value="system" />
<property name="password" value="123" />
</dataSource>
</environment>
Hello reading the documentation from the official site of MyBatis I could obtain the following information:
In case of using the multi-db feature you will need to inform the databaseIdProvider property in the following way:
In case of using the multi-db feature you will need to inform the databaseIdProvider property in the following way:
<bean id="vendorProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="properties">
<props>
<prop key="SQL Server">sqlserver</prop>
<prop key="DB2">db2</prop>
<prop key="Oracle">oracle</prop>
<prop key="MySQL">mysql</prop>
</props>
</property>
</bean>
<bean id="databaseIdProvider" class="org.apache.ibatis.mapping.VendorDatabaseIdProvider">
<property name="properties" ref="vendorProperties"/>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath*:sample/config/mappers/**/*.xml" />
<property name="databaseIdProvider" ref="databaseIdProvider"/>
</bean>
Hope it has been helpful.
Greetings.
NOTE Since 1.3.0, configuration property has been added. It can be specified a Configuration instance directly without MyBatis XML configuration file. For example:
mybatis.org/spring/es/factorybean.html

Tables for entities with boolean fields not created

i tried to switch a connection pool in GlassFish 4 from MySQL to Derby. I am using Spring-Data-JPA with JPA/Hibernate. The problem is that not all tables are created with the derby pool. The tables for entities which have at least one boolean field are not created.
I found nothing in the log files. :(
My applicationContext.xml:
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<context:annotation-config />
<context:component-scan base-package="project" />
<bean
id="dataSource"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property
name="jndiName"
value="serverPool" />
<property
name="lookupOnStartup"
value="false" />
<property
name="proxyInterface"
value="javax.sql.DataSource" />
</bean>
<bean
id="hibernateJpaVendorAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property
name="generateDdl"
value="true" />
<property
name="showSql"
value="true" />
</bean>
<bean
id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property
name="dataSource"
ref="dataSource" />
<property
name="jpaVendorAdapter"
ref="hibernateJpaVendorAdapter" />
<property
name="packagesToScan"
value="project.model.entity" />
</bean>
<bean
id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property
name="entityManagerFactory"
ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<jpa:repositories base-package="project.model.repository" />
</beans>
If the problem is only creating boolean columns, try to use #Column to add DDL statement to the Derby database, I know this decrease portability but it will solve the problem. the property is named columnDefinition. http://docs.oracle.com/javaee/6/api/javax/persistence/Column.html
Also I think there need to be something in the log, try to increase the log level.
Okay, i found the solution: I connected to the derby database and executed the command values syscs_util.syscs_get_database_property( 'DataDictionaryVersion' ); The result was 10.1, but version 10.7 is necessary for boolean support. I then renamed the database name in the derby pool inside GlassFish (its by default sun-appserv-samples) and now all tables are created. With the new database the command gave me version 10.9.