/* * 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.test.annotations.enumerated; import java.io.Serializable; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import java.util.List; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.criterion.Restrictions; import org.hibernate.dialect.AbstractHANADialect; import org.hibernate.dialect.Oracle8iDialect; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.mapping.PersistentClass; import org.hibernate.type.EnumType; import org.hibernate.type.Type; import org.hibernate.testing.SkipForDialect; import org.hibernate.testing.TestForIssue; import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase; import org.hibernate.test.annotations.enumerated.custom_types.FirstLetterType; import org.hibernate.test.annotations.enumerated.custom_types.LastNumberType; import org.hibernate.test.annotations.enumerated.enums.Common; import org.hibernate.test.annotations.enumerated.enums.FirstLetter; import org.hibernate.test.annotations.enumerated.enums.LastNumber; import org.hibernate.test.annotations.enumerated.enums.Trimmed; import org.junit.Test; import static org.junit.Assert.assertEquals; /** * Test type definition for enum * * @author Janario Oliveira */ public class EnumeratedTypeTest extends BaseNonConfigCoreFunctionalTestCase { @Test public void testTypeDefinition() { PersistentClass pc = metadata().getEntityBinding( EntityEnum.class.getName() ); // ordinal default of EnumType Type ordinalEnum = pc.getProperty( "ordinal" ).getType(); assertEquals( Common.class, ordinalEnum.getReturnedClass() ); assertEquals( EnumType.class.getName(), ordinalEnum.getName() ); // string defined by Enumerated(STRING) Type stringEnum = pc.getProperty( "string" ).getType(); assertEquals( Common.class, stringEnum.getReturnedClass() ); assertEquals( EnumType.class.getName(), stringEnum.getName() ); // explicit defined by @Type Type first = pc.getProperty( "firstLetter" ).getType(); assertEquals( FirstLetter.class, first.getReturnedClass() ); assertEquals( FirstLetterType.class.getName(), first.getName() ); // implicit defined by @TypeDef in somewhere Type last = pc.getProperty( "lastNumber" ).getType(); assertEquals( LastNumber.class, last.getReturnedClass() ); assertEquals( LastNumberType.class.getName(), last.getName() ); // implicit defined by @TypeDef in anywhere, but overrided by Enumerated(STRING) Type implicitOverrideExplicit = pc.getProperty( "explicitOverridingImplicit" ).getType(); assertEquals( LastNumber.class, implicitOverrideExplicit.getReturnedClass() ); assertEquals( EnumType.class.getName(), implicitOverrideExplicit.getName() ); } @Test public void testTypeQuery() { Session session = openSession(); session.getTransaction().begin(); // persist EntityEnum entityEnum = new EntityEnum(); entityEnum.setOrdinal( Common.A2 ); Serializable id = session.save( entityEnum ); session.getTransaction().commit(); session.close(); session = openSession(); session.getTransaction().begin(); // find entityEnum = (EntityEnum) session.createQuery( "from EntityEnum ee where ee.ordinal=1" ).uniqueResult(); assertEquals( id, entityEnum.getId() ); assertEquals( Common.A2, entityEnum.getOrdinal() ); // find parameter entityEnum = (EntityEnum) session.createQuery( "from EntityEnum ee where ee.ordinal=:ordinal" ) .setParameter( "ordinal", Common.A2 ).uniqueResult(); assertEquals( id, entityEnum.getId() ); assertEquals( Common.A2, entityEnum.getOrdinal() ); // delete assertEquals( 1, session.createSQLQuery( "DELETE FROM EntityEnum where ordinal=1" ).executeUpdate() ); session.getTransaction().commit(); session.close(); // ************** session = openSession(); session.getTransaction().begin(); // persist entityEnum = new EntityEnum(); entityEnum.setString( Common.B1 ); id = session.save( entityEnum ); session.getTransaction().commit(); session.close(); session = openSession(); session.getTransaction().begin(); // find entityEnum = (EntityEnum) session.createQuery( "from EntityEnum ee where ee.string='B1'" ).uniqueResult(); assertEquals( id, entityEnum.getId() ); assertEquals( Common.B1, entityEnum.getString() ); // find parameter entityEnum = (EntityEnum) session.createQuery( "from EntityEnum ee where ee.string=:string" ) .setParameter( "string", Common.B1 ).uniqueResult(); assertEquals( id, entityEnum.getId() ); assertEquals( Common.B1, entityEnum.getString() ); // delete assertEquals( 1, session.createSQLQuery( "DELETE FROM EntityEnum where string='B1'" ).executeUpdate() ); session.getTransaction().commit(); session.close(); // ************** session = openSession(); session.getTransaction().begin(); // persist entityEnum = new EntityEnum(); entityEnum.setFirstLetter( FirstLetter.C_LETTER ); id = session.save( entityEnum ); session.getTransaction().commit(); session.close(); session = openSession(); session.getTransaction().begin(); // find entityEnum = (EntityEnum) session.createQuery( "from EntityEnum ee where ee.firstLetter='C'" ).uniqueResult(); assertEquals( id, entityEnum.getId() ); assertEquals( FirstLetter.C_LETTER, entityEnum.getFirstLetter() ); // find parameter entityEnum = (EntityEnum) session.createQuery( "from EntityEnum ee where ee.firstLetter=:firstLetter" ) .setParameter( "firstLetter", FirstLetter.C_LETTER ).uniqueResult(); assertEquals( id, entityEnum.getId() ); assertEquals( FirstLetter.C_LETTER, entityEnum.getFirstLetter() ); // delete assertEquals( 1, session.createSQLQuery( "DELETE FROM EntityEnum where firstLetter='C'" ).executeUpdate() ); session.getTransaction().commit(); session.close(); // ************** session = openSession(); session.getTransaction().begin(); // persist entityEnum = new EntityEnum(); entityEnum.setLastNumber( LastNumber.NUMBER_1 ); id = session.save( entityEnum ); session.getTransaction().commit(); session.close(); session = openSession(); session.getTransaction().begin(); // find entityEnum = (EntityEnum) session.createQuery( "from EntityEnum ee where ee.lastNumber='1'" ).uniqueResult(); assertEquals( id, entityEnum.getId() ); assertEquals( LastNumber.NUMBER_1, entityEnum.getLastNumber() ); // find parameter entityEnum = (EntityEnum) session.createQuery( "from EntityEnum ee where ee.lastNumber=:lastNumber" ) .setParameter( "lastNumber", LastNumber.NUMBER_1 ).uniqueResult(); assertEquals( id, entityEnum.getId() ); assertEquals( LastNumber.NUMBER_1, entityEnum.getLastNumber() ); // delete assertEquals( 1, session.createSQLQuery( "DELETE FROM EntityEnum where lastNumber='1'" ).executeUpdate() ); session.getTransaction().commit(); session.close(); // ************** session = openSession(); session.getTransaction().begin(); // persist entityEnum = new EntityEnum(); entityEnum.setExplicitOverridingImplicit( LastNumber.NUMBER_2 ); id = session.save( entityEnum ); session.getTransaction().commit(); session.close(); session = openSession(); session.getTransaction().begin(); // find entityEnum = (EntityEnum) session.createQuery( "from EntityEnum ee where ee.explicitOverridingImplicit='NUMBER_2'" ).uniqueResult(); assertEquals( id, entityEnum.getId() ); assertEquals( LastNumber.NUMBER_2, entityEnum.getExplicitOverridingImplicit() ); // find parameter entityEnum = (EntityEnum) session .createQuery( "from EntityEnum ee where ee.explicitOverridingImplicit=:override" ) .setParameter( "override", LastNumber.NUMBER_2 ).uniqueResult(); assertEquals( id, entityEnum.getId() ); assertEquals( LastNumber.NUMBER_2, entityEnum.getExplicitOverridingImplicit() ); // delete assertEquals( 1, session.createSQLQuery( "DELETE FROM EntityEnum where explicitOverridingImplicit='NUMBER_2'" ) .executeUpdate() ); session.getTransaction().commit(); session.close(); } @Test public void testTypeCriteria() { Session session = openSession(); session.getTransaction().begin(); // persist EntityEnum entityEnum = new EntityEnum(); entityEnum.setOrdinal( Common.A1 ); Serializable id = session.save( entityEnum ); session.getTransaction().commit(); session.close(); session = openSession(); session.getTransaction().begin(); // find entityEnum = (EntityEnum) session.createCriteria( EntityEnum.class ) .add( Restrictions.eq( "ordinal", Common.A1 ) ).uniqueResult(); assertEquals( id, entityEnum.getId() ); assertEquals( Common.A1, entityEnum.getOrdinal() ); // delete assertEquals( 1, session.createSQLQuery( "DELETE FROM EntityEnum where ordinal=0" ).executeUpdate() ); session.getTransaction().commit(); session.close(); // ************** session = openSession(); session.getTransaction().begin(); // persist entityEnum = new EntityEnum(); entityEnum.setString( Common.B2 ); id = session.save( entityEnum ); session.getTransaction().commit(); session.close(); session = openSession(); session.getTransaction().begin(); // find entityEnum = (EntityEnum) session.createCriteria( EntityEnum.class ) .add( Restrictions.eq( "string", Common.B2 ) ).uniqueResult(); assertEquals( id, entityEnum.getId() ); assertEquals( Common.B2, entityEnum.getString() ); // delete assertEquals( 1, session.createSQLQuery( "DELETE FROM EntityEnum where string='B2'" ).executeUpdate() ); session.getTransaction().commit(); session.close(); // ************** session = openSession(); session.getTransaction().begin(); // persist entityEnum = new EntityEnum(); entityEnum.setFirstLetter( FirstLetter.A_LETTER ); id = session.save( entityEnum ); session.getTransaction().commit(); session.close(); session = openSession(); session.getTransaction().begin(); // find entityEnum = (EntityEnum) session.createCriteria( EntityEnum.class ) .add( Restrictions.eq( "firstLetter", FirstLetter.A_LETTER ) ).uniqueResult(); assertEquals( id, entityEnum.getId() ); assertEquals( FirstLetter.A_LETTER, entityEnum.getFirstLetter() ); // delete assertEquals( 1, session.createSQLQuery( "DELETE FROM EntityEnum where firstLetter='A'" ).executeUpdate() ); session.getTransaction().commit(); session.close(); // ************** session = openSession(); session.getTransaction().begin(); // persist entityEnum = new EntityEnum(); entityEnum.setLastNumber( LastNumber.NUMBER_3 ); id = session.save( entityEnum ); session.getTransaction().commit(); session.close(); session = openSession(); session.getTransaction().begin(); // find entityEnum = (EntityEnum) session.createCriteria( EntityEnum.class ) .add( Restrictions.eq( "lastNumber", LastNumber.NUMBER_3 ) ).uniqueResult(); assertEquals( id, entityEnum.getId() ); assertEquals( LastNumber.NUMBER_3, entityEnum.getLastNumber() ); // delete assertEquals( 1, session.createSQLQuery( "DELETE FROM EntityEnum where lastNumber='3'" ).executeUpdate() ); session.getTransaction().commit(); session.close(); // ************** session = openSession(); session.getTransaction().begin(); // persist entityEnum = new EntityEnum(); entityEnum.setExplicitOverridingImplicit( LastNumber.NUMBER_2 ); id = session.save( entityEnum ); session.getTransaction().commit(); session.close(); session = openSession(); session.getTransaction().begin(); // find entityEnum = (EntityEnum) session.createCriteria( EntityEnum.class ) .add( Restrictions.eq( "explicitOverridingImplicit", LastNumber.NUMBER_2 ) ).uniqueResult(); assertEquals( id, entityEnum.getId() ); assertEquals( LastNumber.NUMBER_2, entityEnum.getExplicitOverridingImplicit() ); // delete assertEquals( 1, session.createSQLQuery( "DELETE FROM EntityEnum where explicitOverridingImplicit='NUMBER_2'" ) .executeUpdate() ); session.getTransaction().commit(); session.close(); } @Test @TestForIssue(jiraKey = "HHH-4699") @SkipForDialect(value = { Oracle8iDialect.class, AbstractHANADialect.class }, jiraKey = "HHH-8516", comment = "HHH-4699 was specifically for using a CHAR, but Oracle/HANA do not handle the 2nd query correctly without VARCHAR. ") public void testTrimmedEnumChar() throws SQLException { // use native SQL to insert, forcing whitespace to occur final Session s = openSession(); final Connection connection = ((SessionImplementor)s).connection(); final Statement statement = connection.createStatement(); statement.execute("insert into EntityEnum (id, trimmed) values(1, '" + Trimmed.A.name() + "')"); statement.execute("insert into EntityEnum (id, trimmed) values(2, '" + Trimmed.B.name() + "')"); s.getTransaction().begin(); // ensure EnumType can do #fromName with the trimming List<EntityEnum> resultList = s.createQuery("select e from EntityEnum e").list(); assertEquals( resultList.size(), 2 ); assertEquals( resultList.get(0).getTrimmed(), Trimmed.A ); assertEquals( resultList.get(1).getTrimmed(), Trimmed.B ); // ensure querying works final Query query = s.createQuery("select e from EntityEnum e where e.trimmed=?"); query.setParameter( 0, Trimmed.A ); resultList = query.list(); assertEquals( resultList.size(), 1 ); assertEquals( resultList.get(0).getTrimmed(), Trimmed.A ); statement.execute( "delete from EntityEnum" ); s.getTransaction().commit(); s.close(); } @Test @TestForIssue(jiraKey = "HHH-9369") public void testFormula() throws SQLException { // use native SQL to insert, forcing whitespace to occur final Session s = openSession(); final Connection connection = ((SessionImplementor)s).connection(); final Statement statement = connection.createStatement(); statement.execute("insert into EntityEnum (id) values(1)"); s.getTransaction().begin(); // ensure EnumType can do #fromName with the trimming List<EntityEnum> resultList = s.createQuery("select e from EntityEnum e").list(); assertEquals( resultList.size(), 1 ); assertEquals( resultList.get(0).getFormula(), Trimmed.A ); statement.execute( "delete from EntityEnum" ); s.getTransaction().commit(); s.close(); } @Test @TestForIssue(jiraKey = "HHH-9605") public void testSet() throws SQLException { // ************** Session session = openSession(); session.getTransaction().begin(); // persist EntityEnum entityEnum = new EntityEnum(); entityEnum.setString( Common.B2 ); entityEnum.getSet().add( Common.B2 ); Serializable id = session.save( entityEnum ); session.getTransaction().commit(); session.close(); session = openSession(); session.getTransaction().begin(); String sql = "select e from EntityEnum e where :param in elements( e.set ) "; Query queryObject = session.createQuery( sql ); queryObject.setParameter( "param", Common.B2 ); // ensure EnumType can do #fromName with the trimming List<EntityEnum> resultList = queryObject.list(); assertEquals( resultList.size(), 1 ); entityEnum = resultList.get( 0 ); assertEquals( id, entityEnum.getId() ); assertEquals( Common.B2, entityEnum.getSet().iterator().next() ); // delete assertEquals( 1, session.createSQLQuery( "DELETE FROM set_enum" ).executeUpdate() ); assertEquals( 1, session.createSQLQuery( "DELETE FROM EntityEnum" ).executeUpdate() ); session.getTransaction().commit(); session.close(); } @Override protected Class[] getAnnotatedClasses() { return new Class[] { EntityEnum.class }; } }