HHH-11457 - Add MariaDB specific Dialects

This commit is contained in:
Vlad Mihalcea 2017-02-08 13:08:02 +02:00
parent 35211ee5f3
commit 7c06d003dc
38 changed files with 323 additions and 219 deletions

View File

@ -45,11 +45,11 @@ ext {
'jdbc.url' : 'jdbc:mysql://localhost/hibernate_orm_test'
],
mariadb : [
'db.dialect' : 'org.hibernate.dialect.MySQL57InnoDBDialect',
'db.dialect' : 'org.hibernate.dialect.MariaDB53Dialect',
'jdbc.driver': 'org.mariadb.jdbc.Driver',
'jdbc.user' : 'hibernate_orm_test',
'jdbc.pass' : 'hibernate_orm_test',
'jdbc.url' : 'jdbc:mariadb://localhost/hibernate_orm_test'
'jdbc.url' : 'jdbc:mariadb://127.0.0.1/hibernate_orm_test'
],
postgis : [
'db.dialect' : 'org.hibernate.spatial.dialect.postgis.PostgisDialect',

View File

@ -63,6 +63,7 @@ dependencies {
testCompile( project(':hibernate-testing') )
testCompile( libraries.mockito )
testCompile( libraries.mockito_inline )
testRuntime( libraries.h2 )
testRuntime( libraries.hsqldb )
testRuntime( libraries.postgresql )

View File

@ -43,7 +43,7 @@ import javax.persistence.Version;
name = "find_person_name",
query =
"SELECT name " +
"FROM person "
"FROM Person "
),
//end::sql-scalar-NamedNativeQuery-example[]
//tag::sql-multiple-scalar-values-NamedNativeQuery-example[]
@ -53,7 +53,7 @@ import javax.persistence.Version;
"SELECT " +
" name, " +
" nickName " +
"FROM person "
"FROM Person "
),
//end::sql-multiple-scalar-values-NamedNativeQuery-example[]
// tag::sql-multiple-scalar-values-dto-NamedNativeQuery-example[]
@ -63,7 +63,7 @@ import javax.persistence.Version;
"SELECT " +
" name, " +
" nickName " +
"FROM person ",
"FROM Person ",
resultSetMapping = "name_and_nickName_dto"
),
//end::sql-multiple-scalar-values-dto-NamedNativeQuery-example[]
@ -78,7 +78,7 @@ import javax.persistence.Version;
" p.address AS \"address\", " +
" p.createdOn AS \"createdOn\", " +
" p.version AS \"version\" " +
"FROM person p " +
"FROM Person p " +
"WHERE p.name LIKE :name",
resultClass = Person.class
),
@ -98,8 +98,8 @@ import javax.persistence.Version;
" ph.person_id AS \"ph.person_id\", " +
" ph.phone_number AS \"ph.number\", " +
" ph.phone_type AS \"ph.type\" " +
"FROM person pr " +
"JOIN phone ph ON pr.id = ph.person_id " +
"FROM Person pr " +
"JOIN Phone ph ON pr.id = ph.person_id " +
"WHERE pr.name LIKE :name",
resultSetMapping = "person_with_phones"
)

View File

@ -238,7 +238,7 @@ public class PersistenceContextTest extends BaseEntityManagerFunctionalTestCase
session.doWork( connection -> {
try(Statement statement = connection.createStatement()) {
statement.executeUpdate( "UPDATE person SET name = UPPER(name)" );
statement.executeUpdate( "UPDATE Person SET name = UPPER(name)" );
}
} );

View File

@ -66,8 +66,8 @@ public class MySQLStoredProcedureTest extends BaseEntityManagerFunctionalTestCas
") " +
"BEGIN " +
" SELECT COUNT(*) INTO phoneCount " +
" FROM phone " +
" WHERE phone.person_id = personId; " +
" FROM Phone p " +
" WHERE p.person_id = personId; " +
"END"
);
//end::sql-sp-out-mysql-example[]
@ -76,7 +76,7 @@ public class MySQLStoredProcedureTest extends BaseEntityManagerFunctionalTestCas
"CREATE PROCEDURE sp_phones(IN personId INT) " +
"BEGIN " +
" SELECT * " +
" FROM phone " +
" FROM Phone " +
" WHERE person_id = personId; " +
"END"
);
@ -90,8 +90,8 @@ public class MySQLStoredProcedureTest extends BaseEntityManagerFunctionalTestCas
"BEGIN " +
" DECLARE phoneCount integer; " +
" SELECT COUNT(*) INTO phoneCount " +
" FROM phone " +
" WHERE phone.person_id = personId; " +
" FROM Phone p " +
" WHERE p.person_id = personId; " +
" RETURN phoneCount; " +
"END"
);

View File

@ -154,7 +154,7 @@ public class SQLTest extends BaseEntityManagerFunctionalTestCase {
doInJPA( this::entityManagerFactory, entityManager -> {
//tag::sql-jpa-all-columns-scalar-query-example[]
List<Object[]> persons = entityManager.createNativeQuery(
"SELECT * FROM person" )
"SELECT * FROM Person" )
.getResultList();
//end::sql-jpa-all-columns-scalar-query-example[]
assertEquals( 3, persons.size() );
@ -166,7 +166,7 @@ public class SQLTest extends BaseEntityManagerFunctionalTestCase {
doInJPA( this::entityManagerFactory, entityManager -> {
//tag::sql-jpa-custom-column-selection-scalar-query-example[]
List<Object[]> persons = entityManager.createNativeQuery(
"SELECT id, name FROM person" )
"SELECT id, name FROM Person" )
.getResultList();
for(Object[] person : persons) {
@ -185,7 +185,7 @@ public class SQLTest extends BaseEntityManagerFunctionalTestCase {
Session session = entityManager.unwrap( Session.class );
//tag::sql-hibernate-all-columns-scalar-query-example[]
List<Object[]> persons = session.createSQLQuery(
"SELECT * FROM person" )
"SELECT * FROM Person" )
.list();
//end::sql-hibernate-all-columns-scalar-query-example[]
assertEquals(3, persons.size());
@ -198,7 +198,7 @@ public class SQLTest extends BaseEntityManagerFunctionalTestCase {
Session session = entityManager.unwrap( Session.class );
//tag::sql-hibernate-custom-column-selection-scalar-query-example[]
List<Object[]> persons = session.createSQLQuery(
"SELECT id, name FROM person" )
"SELECT id, name FROM Person" )
.list();
for(Object[] person : persons) {
@ -216,7 +216,7 @@ public class SQLTest extends BaseEntityManagerFunctionalTestCase {
Session session = entityManager.unwrap( Session.class );
//tag::sql-hibernate-scalar-query-explicit-result-set-example[]
List<Object[]> persons = session.createSQLQuery(
"SELECT * FROM person" )
"SELECT * FROM Person" )
.addScalar( "id", LongType.INSTANCE )
.addScalar( "name", StringType.INSTANCE )
.list();
@ -237,7 +237,7 @@ public class SQLTest extends BaseEntityManagerFunctionalTestCase {
Session session = entityManager.unwrap( Session.class );
//tag::sql-hibernate-scalar-query-partial-explicit-result-set-example[]
List<Object[]> persons = session.createSQLQuery(
"SELECT * FROM person" )
"SELECT * FROM Person" )
.addScalar( "id", LongType.INSTANCE )
.addScalar( "name" )
.list();
@ -256,7 +256,7 @@ public class SQLTest extends BaseEntityManagerFunctionalTestCase {
doInJPA( this::entityManagerFactory, entityManager -> {
//tag::sql-jpa-entity-query-example[]
List<Person> persons = entityManager.createNativeQuery(
"SELECT * FROM person", Person.class )
"SELECT * FROM Person", Person.class )
.getResultList();
//end::sql-jpa-entity-query-example[]
assertEquals(3, persons.size());
@ -269,7 +269,7 @@ public class SQLTest extends BaseEntityManagerFunctionalTestCase {
Session session = entityManager.unwrap( Session.class );
//tag::sql-hibernate-entity-query-example[]
List<Person> persons = session.createSQLQuery(
"SELECT * FROM person" )
"SELECT * FROM Person" )
.addEntity( Person.class )
.list();
//end::sql-hibernate-entity-query-example[]
@ -283,7 +283,7 @@ public class SQLTest extends BaseEntityManagerFunctionalTestCase {
//tag::sql-jpa-entity-query-explicit-result-set-example[]
List<Person> persons = entityManager.createNativeQuery(
"SELECT id, name, nickName, address, createdOn, version " +
"FROM person", Person.class )
"FROM Person", Person.class )
.getResultList();
//end::sql-jpa-entity-query-explicit-result-set-example[]
assertEquals(3, persons.size());
@ -297,7 +297,7 @@ public class SQLTest extends BaseEntityManagerFunctionalTestCase {
//tag::sql-hibernate-entity-query-explicit-result-set-example[]
List<Person> persons = session.createSQLQuery(
"SELECT id, name, nickName, address, createdOn, version " +
"FROM person" )
"FROM Person" )
.addEntity( Person.class )
.list();
//end::sql-hibernate-entity-query-explicit-result-set-example[]
@ -311,7 +311,7 @@ public class SQLTest extends BaseEntityManagerFunctionalTestCase {
//tag::sql-jpa-entity-associations-query-many-to-one-example[]
List<Phone> phones = entityManager.createNativeQuery(
"SELECT id, phone_number, phone_type, person_id " +
"FROM phone", Phone.class )
"FROM Phone", Phone.class )
.getResultList();
//end::sql-jpa-entity-associations-query-many-to-one-example[]
assertEquals(3, phones.size());
@ -325,7 +325,7 @@ public class SQLTest extends BaseEntityManagerFunctionalTestCase {
//tag::sql-hibernate-entity-associations-query-many-to-one-example[]
List<Phone> phones = session.createSQLQuery(
"SELECT id, phone_number, phone_type, person_id " +
"FROM phone" )
"FROM Phone" )
.addEntity( Phone.class )
.list();
//end::sql-hibernate-entity-associations-query-many-to-one-example[]
@ -339,8 +339,8 @@ public class SQLTest extends BaseEntityManagerFunctionalTestCase {
//tag::sql-jpa-entity-associations-query-many-to-one-join-example[]
List<Phone> phones = entityManager.createNativeQuery(
"SELECT * " +
"FROM phone ph " +
"JOIN person pr ON ph.person_id = pr.id", Phone.class )
"FROM Phone ph " +
"JOIN Person pr ON ph.person_id = pr.id", Phone.class )
.getResultList();
for(Phone phone : phones) {
@ -358,8 +358,8 @@ public class SQLTest extends BaseEntityManagerFunctionalTestCase {
//tag::sql-hibernate-entity-associations-query-many-to-one-join-example[]
List<Object[]> tuples = session.createSQLQuery(
"SELECT * " +
"FROM phone ph " +
"JOIN person pr ON ph.person_id = pr.id" )
"FROM Phone ph " +
"JOIN Person pr ON ph.person_id = pr.id" )
.addEntity("phone", Phone.class )
.addJoin( "pr", "phone.person")
.list();
@ -380,8 +380,8 @@ public class SQLTest extends BaseEntityManagerFunctionalTestCase {
//tag::sql-hibernate-entity-associations-query-many-to-one-join-result-transformer-example[]
List<Person> persons = session.createSQLQuery(
"SELECT * " +
"FROM phone ph " +
"JOIN person pr ON ph.person_id = pr.id" )
"FROM Phone ph " +
"JOIN Person pr ON ph.person_id = pr.id" )
.addEntity("phone", Phone.class )
.addJoin( "pr", "phone.person")
.setResultTransformer( Criteria.ROOT_ENTITY )
@ -404,7 +404,7 @@ public class SQLTest extends BaseEntityManagerFunctionalTestCase {
//tag::sql-jpa-entity-associations-query-one-to-many-join-example[]
List<Phone> phones = entityManager.createNativeQuery(
"SELECT * " +
"FROM phone ph " +
"FROM Phone ph " +
"JOIN phone_call c ON c.phone_id = ph.id", Phone.class )
.getResultList();
@ -423,7 +423,7 @@ public class SQLTest extends BaseEntityManagerFunctionalTestCase {
Session session = entityManager.unwrap( Session.class );
List<Phone> phones = session.createSQLQuery(
"SELECT * " +
"FROM phone ph " +
"FROM Phone ph " +
"JOIN phone_call c ON c.phone_id = ph.id" )
.addEntity("phone", Phone.class )
.addJoin( "c", "phone.calls")
@ -452,7 +452,7 @@ public class SQLTest extends BaseEntityManagerFunctionalTestCase {
//tag::sql-hibernate-entity-associations-query-one-to-many-join-example[]
List<Object[]> tuples = session.createSQLQuery(
"SELECT * " +
"FROM phone ph " +
"FROM Phone ph " +
"JOIN phone_call c ON c.phone_id = ph.id" )
.addEntity("phone", Phone.class )
.addJoin( "c", "phone.calls")
@ -474,7 +474,7 @@ public class SQLTest extends BaseEntityManagerFunctionalTestCase {
//tag::sql-jpa-multi-entity-query-example[]
List<Object> entities = entityManager.createNativeQuery(
"SELECT * " +
"FROM person pr, partner pt " +
"FROM Person pr, Partner pt " +
"WHERE pr.name = pt.name" )
.getResultList();
//end::sql-jpa-multi-entity-query-example[]
@ -495,7 +495,7 @@ public class SQLTest extends BaseEntityManagerFunctionalTestCase {
//tag::sql-hibernate-multi-entity-query-example[]
List<Object> entities = session.createSQLQuery(
"SELECT * " +
"FROM person pr, partner pt " +
"FROM Person pr, Partner pt " +
"WHERE pr.name = pt.name" )
.list();
//end::sql-hibernate-multi-entity-query-example[]
@ -518,7 +518,7 @@ public class SQLTest extends BaseEntityManagerFunctionalTestCase {
//tag::sql-hibernate-multi-entity-query-alias-example[]
List<Object> entities = session.createSQLQuery(
"SELECT {pr.*}, {pt.*} " +
"FROM person pr, partner pt " +
"FROM Person pr, Partner pt " +
"WHERE pr.name = pt.name" )
.addEntity( "pr", Person.class)
.addEntity( "pt", Partner.class)
@ -535,7 +535,7 @@ public class SQLTest extends BaseEntityManagerFunctionalTestCase {
//tag::sql-hibernate-dto-query-example[]
List<PersonSummaryDTO> dtos = session.createSQLQuery(
"SELECT p.id as \"id\", p.name as \"name\" " +
"FROM person p")
"FROM Person p")
.setResultTransformer( Transformers.aliasToBean( PersonSummaryDTO.class ) )
.list();
//end::sql-hibernate-dto-query-example[]
@ -565,7 +565,7 @@ public class SQLTest extends BaseEntityManagerFunctionalTestCase {
//tag::sql-jpa-query-parameters-example[]
List<Person> persons = entityManager.createNativeQuery(
"SELECT * " +
"FROM person " +
"FROM Person " +
"WHERE name like :name", Person.class )
.setParameter("name", "J%")
.getResultList();
@ -581,7 +581,7 @@ public class SQLTest extends BaseEntityManagerFunctionalTestCase {
//tag::sql-hibernate-query-parameters-example[]
List<Person> persons = session.createSQLQuery(
"SELECT * " +
"FROM person " +
"FROM Person " +
"WHERE name like :name" )
.addEntity( Person.class )
.setParameter("name", "J%")

View File

@ -76,6 +76,7 @@ dependencies {
testCompile( libraries.jandex )
testCompile( libraries.classmate )
testCompile( libraries.mockito )
testCompile( libraries.mockito_inline )
testCompile( 'joda-time:joda-time:2.3' )
// testCompile( "org.jboss.weld:weld-core:2.3.4.Final" )
// testCompile( "org.jboss.arquillian.container:arquillian-weld-ee-embedded-1.1:1.0.0.CR9" )

View File

@ -0,0 +1,63 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.dialect;
import java.sql.Types;
import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.dialect.function.StaticPrecisionFspTimestampFunction;
/**
* @author Vlad Mihalcea
*/
public class MariaDB53Dialect extends MariaDBDialect {
public MariaDB53Dialect() {
super();
// For details about MariaDB 5.3 support for fractional seconds
// precision (fsp): https://mariadb.com/kb/en/mariadb/microseconds-in-mariadb/
// Regarding datetime(fsp), "The fsp value, if given, must be
// in the range 0 to 6. A value of 0 signifies that there is
// no fractional part. If omitted, the default precision is 0.
// (This differs from the standard SQL default of 6, for
// compatibility with previous MariaDB versions.)".
// The following is defined because Hibernate currently expects
// the SQL 1992 default of 6 (which is inconsistent with the MariaDB
// default).
registerColumnType( Types.TIMESTAMP, "datetime(6)" );
// MariaDB also supports fractional seconds precision for time values
// (time(fsp)). According to SQL 1992, the default for <time precision>
// is 0. The MariaDB default is time(0), there's no need to override
// the setting for Types.TIME columns.
// For details about MariaDB support for timestamp functions, see:
// http://dev.MariaDB.com/doc/refman/5.7/en/date-and-time-functions.html
// The following are synonyms for now(fsp), where fsp defaults to 0 on MariaDB 5.3:
// current_timestamp([fsp]), localtime(fsp), localtimestamp(fsp).
// Register the same StaticPrecisionFspTimestampFunction for all 4 functions.
final SQLFunction currentTimestampFunction = new StaticPrecisionFspTimestampFunction( "now", 6 );
registerFunction( "now", currentTimestampFunction );
registerFunction( "current_timestamp", currentTimestampFunction );
registerFunction( "localtime", currentTimestampFunction );
registerFunction( "localtimestamp", currentTimestampFunction );
// sysdate is different from now():
// "SYSDATE() returns the time at which it executes. This differs
// from the behavior for NOW(), which returns a constant time that
// indicates the time at which the statement began to execute.
// (Within a stored function or trigger, NOW() returns the time at
// which the function or triggering statement began to execute.)
registerFunction( "sysdate", new StaticPrecisionFspTimestampFunction( "sysdate", 6 ) );
// from_unixtime(), timestamp() are functions that return TIMESTAMP that do not support a
// fractional seconds precision argument (so there's no need to override them here):
}
}

View File

@ -0,0 +1,20 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.dialect;
/**
* @author Vlad Mihalcea
*/
public class MariaDBDialect extends MySQL5InnoDBDialect {
public MariaDBDialect() {
super();
}
public boolean supportsRowValueConstructorSyntaxInInList() {
return true;
}
}

View File

@ -83,7 +83,7 @@ public class NativeQueryOrdinalParametersTest extends BaseEntityManagerFunctiona
public void testNativeQueryIndexedOrdinalParameter() {
EntityManager em = getOrCreateEntityManager();
try {
Query query = em.createNativeQuery( "SELECT * FROM Game g WHERE title = ?1" );
Query query = em.createNativeQuery( "SELECT * FROM GAME g WHERE title = ?1" );
query.setParameter( 1, "Super Mario Brothers" );
List list = query.getResultList();
assertEquals( 1, list.size() );
@ -98,7 +98,7 @@ public class NativeQueryOrdinalParametersTest extends BaseEntityManagerFunctiona
public void testNativeQueryOrdinalParameter() {
EntityManager em = getOrCreateEntityManager();
try {
Query query = em.createNativeQuery( "SELECT * FROM Game g WHERE title = ?" );
Query query = em.createNativeQuery( "SELECT * FROM GAME g WHERE title = ?" );
query.setParameter( 1, "Super Mario Brothers" );
List list = query.getResultList();
assertEquals( 1, list.size() );
@ -112,7 +112,7 @@ public class NativeQueryOrdinalParametersTest extends BaseEntityManagerFunctiona
@TestForIssue( jiraKey = "HHH-11121")
public void testConflictWithSessionNativeQuery(){
EntityManager em = getOrCreateEntityManager();
final String sqlString = "SELECT * FROM Game g WHERE title = ?";
final String sqlString = "SELECT * FROM GAME g WHERE title = ?";
try {
NativeQuery sqlQuery = em.unwrap( Session.class ).createSQLQuery( sqlString );
sqlQuery.setString( 0, "Super Mario Brothers").setCacheable( true );

View File

@ -142,7 +142,7 @@ public class NotFoundTest extends BaseCoreFunctionalTestCase {
}
}
@Entity(name = "Show")
@Entity(name = "T_Show")
public static class Show {
@Id

View File

@ -71,7 +71,7 @@ public abstract class AbstractBulkIdTest extends BaseCoreFunctionalTestCase {
}
protected int entityCount() {
return 100;
return 10;
}
@Test

View File

@ -8,6 +8,9 @@ package org.hibernate.test.bytecode.enhancement.javassist;
import java.io.FileNotFoundException;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import javassist.CtClass;
@ -18,8 +21,6 @@ import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.junit.Test;
import org.mockito.Mockito;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
@ -49,7 +50,11 @@ public class EnhancerFileNotFoundTest extends BaseUnitTestCase {
Enhancer enhancer = new Enhancer( enhancementContextMock );
try {
enhancer.loadCtClassFromClass( Mockito.mock( getClass() ).getClass() );
Class<?> clazz = Hidden.class;
String resourceName = Hidden.class.getName().replace( '.', '/' ) + ".class";
URL url = getClass().getClassLoader().getResource( resourceName );
Files.delete( Paths.get(url.toURI()) );
enhancer.loadCtClassFromClass( clazz );
fail("Should throw FileNotFoundException!");
}
catch ( Exception expected ) {
@ -57,4 +62,8 @@ public class EnhancerFileNotFoundTest extends BaseUnitTestCase {
}
}
private static class Hidden {
}
}

View File

@ -202,6 +202,7 @@ public class JoinedInheritanceWithOneToManyTest extends BaseNonConfigCoreFunctio
@Table(name = "TB_BLE_NONLIVING ")
public static class BLENonLiving extends BuildingListEntry {
@Column(name = "is_delayed")
protected boolean delayed;
public boolean isDelayed() {

View File

@ -6,12 +6,16 @@
*/
package org.hibernate.test.locking;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeoutException;
import org.hibernate.LockMode;
import org.hibernate.LockOptions;
import org.hibernate.PessimisticLockException;
import org.hibernate.Session;
import org.hibernate.dialect.MySQLDialect;
import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.dialect.SybaseASE15Dialect;
import org.hibernate.exception.GenericJDBCException;
import org.hibernate.exception.LockAcquisitionException;
@ -23,6 +27,7 @@ import org.hibernate.testing.async.TimedExecutor;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
@ -35,8 +40,11 @@ import static org.junit.Assert.fail;
@SkipForDialect(value=SybaseASE15Dialect.class, strictMatching=true,
comment = "skip this test on Sybase ASE 15.5, but run it on 15.7, see HHH-6820")
public class LockModeTest extends BaseCoreFunctionalTestCase {
private Long id;
private CountDownLatch endLatch = new CountDownLatch( 1 );
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[] { A.class };
@ -44,11 +52,9 @@ public class LockModeTest extends BaseCoreFunctionalTestCase {
@Override
public void prepareTest() throws Exception {
Session session = sessionFactory().openSession();
session.beginTransaction();
id = (Long) session.save( new A( "it" ) );
session.getTransaction().commit();
session.close();
doInHibernate( this::sessionFactory, session -> {
id = (Long) session.save( new A( "it" ) );
} );
}
@Override
protected boolean isCleanupTestDataRequired(){return true;}
@ -57,30 +63,23 @@ public class LockModeTest extends BaseCoreFunctionalTestCase {
@SuppressWarnings( {"deprecation"})
public void testLoading() {
// open a session, begin a transaction and lock row
Session s1 = sessionFactory().openSession();
s1.beginTransaction();
try {
A it = (A) s1.byId( A.class ).with( LockOptions.UPGRADE ).load( id );
doInHibernate( this::sessionFactory, session -> {
A it = session.byId( A.class ).with( LockOptions.UPGRADE ).load( id );
// make sure we got it
assertNotNull( it );
// that initial transaction is still active and so the lock should still be held.
// Lets open another session/transaction and verify that we cannot update the row
nowAttemptToUpdateRow();
}
finally {
s1.getTransaction().commit();
s1.close();
}
} );
}
@Test
public void testLegacyCriteria() {
// open a session, begin a transaction and lock row
Session s1 = sessionFactory().openSession();
s1.beginTransaction();
try {
A it = (A) s1.createCriteria( A.class )
doInHibernate( this::sessionFactory, session -> {
A it = (A) session.createCriteria( A.class )
.setLockMode( LockMode.PESSIMISTIC_WRITE )
.uniqueResult();
// make sure we got it
@ -89,20 +88,14 @@ public class LockModeTest extends BaseCoreFunctionalTestCase {
// that initial transaction is still active and so the lock should still be held.
// Lets open another session/transaction and verify that we cannot update the row
nowAttemptToUpdateRow();
}
finally {
s1.getTransaction().commit();
s1.close();
}
} );
}
@Test
public void testLegacyCriteriaAliasSpecific() {
// open a session, begin a transaction and lock row
Session s1 = sessionFactory().openSession();
s1.beginTransaction();
try {
A it = (A) s1.createCriteria( A.class )
doInHibernate( this::sessionFactory, session -> {
A it = (A) session.createCriteria( A.class )
.setLockMode( "this", LockMode.PESSIMISTIC_WRITE )
.uniqueResult();
// make sure we got it
@ -111,20 +104,14 @@ public class LockModeTest extends BaseCoreFunctionalTestCase {
// that initial transaction is still active and so the lock should still be held.
// Lets open another session/transaction and verify that we cannot update the row
nowAttemptToUpdateRow();
}
finally {
s1.getTransaction().commit();
s1.close();
}
} );
}
@Test
public void testQuery() {
// open a session, begin a transaction and lock row
Session s1 = sessionFactory().openSession();
s1.beginTransaction();
try {
A it = (A) s1.createQuery( "from A a" )
doInHibernate( this::sessionFactory, session -> {
A it = (A) session.createQuery( "from A a" )
.setLockMode( "a", LockMode.PESSIMISTIC_WRITE )
.uniqueResult();
// make sure we got it
@ -133,26 +120,20 @@ public class LockModeTest extends BaseCoreFunctionalTestCase {
// that initial transaction is still active and so the lock should still be held.
// Lets open another session/transaction and verify that we cannot update the row
nowAttemptToUpdateRow();
}
finally {
s1.getTransaction().commit();
s1.close();
}
} );
}
@Test
public void testQueryUsingLockOptions() {
// todo : need an association here to make sure the alias-specific lock modes are applied correctly
Session s1 = sessionFactory().openSession();
s1.beginTransaction();
s1.createQuery( "from A a" )
.setLockOptions( new LockOptions( LockMode.PESSIMISTIC_WRITE ) )
.uniqueResult();
s1.createQuery( "from A a" )
.setLockOptions( new LockOptions().setAliasSpecificLockMode( "a", LockMode.PESSIMISTIC_WRITE ) )
.uniqueResult();
s1.getTransaction().commit();
s1.close();
doInHibernate( this::sessionFactory, session -> {
session.createQuery( "from A a" )
.setLockOptions( new LockOptions( LockMode.PESSIMISTIC_WRITE ) )
.uniqueResult();
session.createQuery( "from A a" )
.setLockOptions( new LockOptions().setAliasSpecificLockMode( "a", LockMode.PESSIMISTIC_WRITE ) )
.uniqueResult();
} );
}
private void nowAttemptToUpdateRow() {
@ -164,64 +145,38 @@ public class LockModeTest extends BaseCoreFunctionalTestCase {
// until the txn in the calling method completed.
// To be able to cater to the second type, we run this block in a separate thread to be able to "time it out"
try {
new TimedExecutor( 10*1000, 1*1000 ).execute(
new Executable() {
Session s;
@Override
public void execute() {
s = sessionFactory().openSession();
s.beginTransaction();
try {
// load with write lock to deal with databases that block (wait indefinitely) direct attempts
// to write a locked row
A it = (A) s.get(
A.class,
id,
new LockOptions( LockMode.PESSIMISTIC_WRITE ).setTimeOut( LockOptions.NO_WAIT )
);
it.setValue( "changed" );
s.flush();
fail( "Pessimistic lock not obtained/held" );
}
catch ( Exception e ) {
// grr, exception can be any number of types based on database
// see HHH-6887
if ( LockAcquisitionException.class.isInstance( e )
|| GenericJDBCException.class.isInstance( e )
|| PessimisticLockException.class.isInstance( e ) ) {
// "ok"
}
else {
fail( "Unexpected error type testing pessimistic locking : " + e.getClass().getName() );
}
}
finally {
shutDown();
}
}
private void shutDown() {
try {
s.getTransaction().rollback();
s.close();
}
catch (Exception ignore) {
}
s = null;
}
@Override
public void timedOut() {
s.cancelQuery();
shutDown();
}
executeSync( () -> {
doInHibernate( this::sessionFactory, _session -> {
_session.doWork( connection -> {
try {
connection.setNetworkTimeout( Executors.newSingleThreadExecutor(), 1000);
} catch (Throwable ignore) {}
} );
try {
// load with write lock to deal with databases that block (wait indefinitely) direct attempts
// to write a locked row
A it = _session.get(
A.class,
id,
new LockOptions( LockMode.PESSIMISTIC_WRITE ).setTimeOut( LockOptions.NO_WAIT )
);
it.setValue( "changed" );
_session.flush();
fail( "Pessimistic lock not obtained/held" );
}
catch ( Exception e ) {
// grr, exception can be any number of types based on database
// see HHH-6887
if ( LockAcquisitionException.class.isInstance( e )
|| GenericJDBCException.class.isInstance( e )
|| PessimisticLockException.class.isInstance( e ) ) {
// "ok"
}
);
}
catch (TimeoutException e) {
// timeout is ok, see rule #2 above
}
else {
fail( "Unexpected error type testing pessimistic locking : " + e.getClass().getName() );
}
}
} );
} );
}
}

View File

@ -67,15 +67,15 @@ public class MySQLStoredProcedureTest extends BaseEntityManagerFunctionalTestCas
") " +
"BEGIN " +
" SELECT COUNT(*) INTO phoneCount " +
" FROM phone " +
" WHERE phone.person_id = personId; " +
" FROM Phone p " +
" WHERE p.person_id = personId; " +
"END"
);
statement.executeUpdate(
"CREATE PROCEDURE sp_phones(IN personId INT) " +
"BEGIN " +
" SELECT * " +
" FROM phone " +
" FROM Phone " +
" WHERE person_id = personId; " +
"END"
);
@ -87,8 +87,8 @@ public class MySQLStoredProcedureTest extends BaseEntityManagerFunctionalTestCas
"BEGIN " +
" DECLARE phoneCount integer; " +
" SELECT COUNT(*) INTO phoneCount " +
" FROM phone " +
" WHERE phone.person_id = personId; " +
" FROM Phone p " +
" WHERE p.person_id = personId; " +
" RETURN phoneCount; " +
"END"
);

View File

@ -157,7 +157,7 @@ public class NativeSQLQueriesTest extends BaseCoreFunctionalTestCase {
{
final NamedSQLQueryDefinitionBuilder builder = new NamedSQLQueryDefinitionBuilder();
builder.setName("namedQuery");
builder.setQuery("select count(*) AS c from organization");
builder.setQuery("select count(*) AS c from ORGANIZATION");
builder.setQueryReturns(new NativeSQLQueryReturn[1]);
sessionFactory().registerNamedSQLQueryDefinition("namedQuery", builder.createNamedQueryDefinition());

View File

@ -11,9 +11,13 @@ package org.hibernate.test.subquery;
import org.hibernate.QueryException;
import org.hibernate.Session;
import org.hibernate.dialect.MariaDBDialect;
import org.hibernate.dialect.PostgreSQL81Dialect;
import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.engine.spi.Mapping;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.testing.SkipForDialect;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.hibernate.type.Type;
import org.junit.Test;
@ -27,6 +31,7 @@ import java.util.function.Consumer;
*
* @author Christian Beikov
*/
@SkipForDialect(value = MariaDBDialect.class, comment = "This version of MariaDB doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery")
public class SubqueryTest extends BaseCoreFunctionalTestCase {
private static final SQLFunction LIMIT_FUNCTION = new SQLFunction() {

View File

@ -20,6 +20,7 @@ import org.junit.Before;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.is;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertThat;
@SkipForDialect({SQLServerDialect.class, SybaseDialect.class})
@ -39,43 +40,45 @@ public class SubselectFetchWithFormulaTest extends BaseNonConfigCoreFunctionalTe
@Before
public void before() {
Session session = openSession();
session.getTransaction().begin();
Name chris = new Name();
chris.setId( 1 );
chris.setName( "chris" );
Value cat = new Value();
cat.setId(1);
cat.setName( chris );
cat.setValue( "cat" );
Value canary = new Value();
canary.setId( 2 );
canary.setName( chris );
canary.setValue( "canary" );
doInHibernate( this::sessionFactory, session -> {
Name chris = new Name();
chris.setId( 1 );
chris.setName( "chris" );
session.persist( chris );
session.persist( cat );
session.persist( canary );
Value cat = new Value();
cat.setId(1);
cat.setName( chris );
cat.setValue( "cat" );
Name sam = new Name();
sam.setId(2);
sam.setName( "sam" );
Value seal = new Value();
seal.setId( 3 );
seal.setName( sam );
seal.setValue( "seal" );
Value snake = new Value();
snake.setId( 4 );
snake.setName( sam );
snake.setValue( "snake" );
Value canary = new Value();
canary.setId( 2 );
canary.setName( chris );
canary.setValue( "canary" );
session.persist( sam );
session.persist(seal);
session.persist( snake );
session.persist( chris );
session.persist( cat );
session.persist( canary );
session.getTransaction().commit();
session.close();
Name sam = new Name();
sam.setId(2);
sam.setName( "sam" );
Value seal = new Value();
seal.setId( 3 );
seal.setName( sam );
seal.setValue( "seal" );
Value snake = new Value();
snake.setId( 4 );
snake.setName( sam );
snake.setValue( "snake" );
session.persist( sam );
session.persist(seal);
session.persist( snake );
} );
}
@After

View File

@ -21,7 +21,9 @@ import javax.persistence.Entity;
import javax.persistence.Id;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.dialect.MariaDBDialect;
import org.hibernate.testing.SkipForDialect;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.hibernate.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import org.junit.Test;
@ -39,6 +41,7 @@ import static org.mockito.Mockito.verify;
/**
* @author Vlad Mihalcea
*/
@SkipForDialect(MariaDBDialect.class)
public class JdbcTimeCustomTimeZoneTest
extends BaseNonConfigCoreFunctionalTestCase {

View File

@ -18,7 +18,9 @@ import javax.persistence.Entity;
import javax.persistence.Id;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.dialect.MariaDBDialect;
import org.hibernate.testing.SkipForDialect;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.hibernate.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import org.junit.Test;
@ -36,6 +38,7 @@ import static org.mockito.Mockito.verify;
/**
* @author Vlad Mihalcea
*/
@SkipForDialect(MariaDBDialect.class)
public class JdbcTimestampCustomSessionLevelTimeZoneTest
extends BaseNonConfigCoreFunctionalTestCase {

View File

@ -18,7 +18,9 @@ import javax.persistence.Entity;
import javax.persistence.Id;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.dialect.MariaDBDialect;
import org.hibernate.testing.SkipForDialect;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.hibernate.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import org.junit.Test;
@ -36,6 +38,7 @@ import static org.mockito.Mockito.verify;
/**
* @author Vlad Mihalcea
*/
@SkipForDialect(MariaDBDialect.class)
public class JdbcTimestampCustomTimeZoneTest
extends BaseNonConfigCoreFunctionalTestCase {

View File

@ -12,6 +12,9 @@ import java.util.concurrent.TimeUnit;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.hibernate.dialect.MariaDBDialect;
import org.hibernate.testing.SkipForDialect;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.junit.Test;
@ -23,6 +26,7 @@ import static org.junit.Assert.assertEquals;
* @author Vlad Mihalcea
*/
@TestForIssue(jiraKey = "HHH-10465")
@SkipForDialect(MariaDBDialect.class)
public class TimeAndTimestampTest extends BaseNonConfigCoreFunctionalTestCase {
@Override

View File

@ -54,7 +54,7 @@ public class PreparedStatementSpyConnectionProvider
}
private Connection spy(Connection connection) {
if ( new MockUtil().isMock( connection ) ) {
if ( MockUtil.isMock( connection ) ) {
return connection;
}
Connection connectionSpy = Mockito.spy( connection );

View File

@ -0,0 +1 @@
mock-maker-inline

View File

@ -11,11 +11,11 @@
<hibernate-mapping>
<class name="org.hibernate.test.subselectfetch.Name" table="Name">
<class name="org.hibernate.test.subselectfetch.Name" table="T_Name">
<id name="id" column="id"/>
<property name="name" column="name"/>
<property name="name" column="c_name"/>
<property name="nameLength" formula="(select length(name) from name where id=name.id)"/>
<property name="nameLength" formula="(select length(c_name) from T_Name where id = T_Name.id)"/>
<bag name="values" inverse="true" lazy="false" fetch="subselect">
<key column="name_id"/>

View File

@ -11,11 +11,11 @@
<hibernate-mapping>
<class name="org.hibernate.test.subselectfetch.Name" table="Name">
<class name="org.hibernate.test.subselectfetch.Name" table="T_Name">
<id name="id" column="id"/>
<property name="name" column="name"/>
<property name="name" column="c_name"/>
<property name="nameLength" formula="(select len(name) from name where id=name.id)"/>
<property name="nameLength" formula="(select len(c_name) from T_Name where id = T_Name.id)"/>
<bag name="values" inverse="true" lazy="false" fetch="subselect">
<key column="name_id"/>

View File

@ -11,9 +11,9 @@
<hibernate-mapping>
<class name="org.hibernate.test.subselectfetch.Value" table="Value">
<class name="org.hibernate.test.subselectfetch.Value" table="T_Value">
<id name="id" column="id"/>
<property name="value" column="value"/>
<property name="value" column="c_value"/>
<many-to-one name="name" column="name_id" insert="false" update="false" />
</class>

View File

@ -9,15 +9,15 @@ package org.hibernate.envers.test.integration.collection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OrderColumn;
import org.hibernate.annotations.IndexColumn;
import org.hibernate.envers.Audited;
import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase;
import org.hibernate.envers.test.Priority;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.transaction.TransactionUtil;
import org.junit.Test;
@ -108,7 +108,7 @@ public class IndexColumnListTest extends BaseEnversJPAFunctionalTestCase {
private Integer id;
@ElementCollection
@IndexColumn(name = "index")
@OrderColumn(name = "`index`")
private List<String> children = new ArrayList<String>();
Parent() {

View File

@ -9,15 +9,15 @@ package org.hibernate.envers.test.integration.manytomany;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.OrderColumn;
import org.hibernate.annotations.IndexColumn;
import org.hibernate.envers.Audited;
import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase;
import org.hibernate.envers.test.Priority;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.transaction.TransactionUtil;
import org.junit.Test;
@ -121,7 +121,7 @@ public class IndexColumnListTest extends BaseEnversJPAFunctionalTestCase {
private Integer id;
@ManyToMany
@IndexColumn(name = "index")
@OrderColumn(name = "`index`")
private List<Child> children = new ArrayList<Child>();
Parent() {

View File

@ -84,7 +84,7 @@ public class GroupMemberTest extends BaseEnversJPAFunctionalTestCase {
private Integer getCurrentAuditUniqueGroupId() {
return TransactionUtil.doInJPA( this::entityManagerFactory, entityManager -> {
final Query query = entityManager.createNativeQuery(
"SELECT uniqueGroup_id FROM groupmember_aud ORDER BY rev DESC"
"SELECT uniqueGroup_id FROM GroupMember_AUD ORDER BY rev DESC"
).setMaxResults( 1 );
final Object result = query.getSingleResult();
assertNotNull( result );

View File

@ -9,16 +9,16 @@ package org.hibernate.envers.test.integration.onetomany;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OrderColumn;
import org.hibernate.annotations.IndexColumn;
import org.hibernate.envers.Audited;
import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase;
import org.hibernate.envers.test.Priority;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.transaction.TransactionUtil;
import org.junit.Test;
@ -122,7 +122,7 @@ public class IndexColumnListTest extends BaseEnversJPAFunctionalTestCase {
private Integer id;
@OneToMany(mappedBy = "parent")
@IndexColumn(name = "index")
@OrderColumn(name = "`index`")
private List<Child> children = new ArrayList<Child>();
Parent() {

View File

@ -17,6 +17,7 @@ import javax.persistence.EntityManager;
import javax.persistence.Query;
import org.hibernate.Session;
import org.hibernate.dialect.MariaDB53Dialect;
import org.hibernate.dialect.MySQL57InnoDBDialect;
import org.hibernate.dialect.MySQL5Dialect;
import org.hibernate.dialect.SybaseASE15Dialect;
@ -474,7 +475,8 @@ public class ValidityAuditStrategyRevEndTsTest extends BaseEnversJPAFunctionalTe
Assert.assertNull( revEnd );
}
else {
if ( getDialect() instanceof MySQL5Dialect && !( getDialect() instanceof MySQL57InnoDBDialect) ) {
if ( getDialect() instanceof MySQL5Dialect &&
!( getDialect() instanceof MySQL57InnoDBDialect || getDialect() instanceof MariaDB53Dialect) ) {
// MySQL5 DATETIME column type does not contain milliseconds.
// MySQL 5.7 supports milliseconds and when MySQL57InnoDBDialect is used, it is assumed that
// the column is defined as DATETIME(6).

View File

@ -16,6 +16,9 @@ import org.hibernate.cfg.AvailableSettings;
import org.hibernate.dialect.Oracle8iDialect;
import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase;
import org.hibernate.envers.test.entities.StrTestEntity;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
import org.junit.Before;
import org.junit.Test;
@ -31,6 +34,7 @@ import static org.junit.Assert.assertTrue;
* @author Chris Cranford
*/
@TestForIssue(jiraKey = "HHH-11131")
@RequiresDialectFeature( DialectChecks.SupportsSequences.class )
public class OrderSequenceGenerationTest extends BaseEnversJPAFunctionalTestCase {
private File createSchema;

View File

@ -25,6 +25,7 @@ dependencies {
testCompile( libraries.jnp_client )
testCompile( libraries.jnp_server )
testCompile( libraries.mockito )
testCompile( libraries.mockito_inline )
testCompile ('mysql:mysql-connector-java:5.1.17')
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -4,6 +4,7 @@ dependencies {
testCompile project( ':hibernate-testing' )
testCompile( libraries.mockito )
testCompile( libraries.mockito_inline )
testRuntime( libraries.ehcache3 )
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -6,6 +6,10 @@
*/
package org.hibernate.testing.junit4;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import javax.transaction.SystemException;
import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper;
@ -35,6 +39,8 @@ public abstract class BaseUnitTestCase {
private ConnectionLeakUtil connectionLeakUtil;
protected final ExecutorService executorService = Executors.newSingleThreadExecutor();
@Rule
public TestRule globalTimeout = new Timeout( 30 * 60 * 1000 ); // no test should run longer than 30 minutes
@ -71,4 +77,20 @@ public abstract class BaseUnitTestCase {
Thread.interrupted();
}
}
protected Future<?> executeAsync(Runnable callable) {
return executorService.submit(callable);
}
protected void executeSync(Runnable callable) {
try {
executeAsync( callable ).get();
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
catch (ExecutionException e) {
e.printStackTrace();
}
}
}

View File

@ -95,16 +95,18 @@ ext {
derby: "org.apache.derby:derby:10.11.1.1",
postgresql: 'org.postgresql:postgresql:9.4-1202-jdbc41',
mysql: 'mysql:mysql-connector-java:6.0.5',
mariadb: 'org.mariadb.jdbc:mariadb-java-client:1.1.7',
mariadb: 'org.mariadb.jdbc:mariadb-java-client:1.5.7',
oracle: 'com.oracle.jdbc:ojdbc7:12.1.0.2',
mariadb: 'org.mariadb.jdbc:mariadb-java-client:1.5.7',
oracle: 'com.oracle.ojdbc:ojdbc7:12.1.0.2.0',
mssql: 'com.microsoft.sqlserver:mssql-jdbc:6.1.0.jre8',
informix: 'com.ibm.informix:jdbc:4.10.7.20160517',
jboss_jta: "org.jboss.jbossts:jbossjta:4.16.4.Final",
xapool: "com.experlog:xapool:1.5.0",
mockito: 'org.mockito:mockito-core:1.9.0',
mockito: 'org.mockito:mockito-core:2.7.5',
mockito_inline: 'org.mockito:mockito-inline:2.7.5',
validator: 'org.hibernate:hibernate-validator:5.2.4.Final',
// EL required by Hibernate Validator at test runtime