From 9f2edb654dd55cee67d1b0445bdc0f6ae716f5e9 Mon Sep 17 00:00:00 2001 From: Gail Badner Date: Thu, 7 Sep 2017 22:01:17 -0700 Subject: [PATCH] HHH-11614 : Revert "HHH-11477 - HQL query against field marked with @Lob fails on PostgreSQL" This reverts commit f0016db20190c3f4dc014486c2f6e64428939f33. --- .../dialect/PostgreSQL81Dialect.java | 2 +- .../descriptor/java/ClobTypeDescriptor.java | 6 - .../descriptor/sql/ClobTypeDescriptor.java | 42 ---- .../org/hibernate/test/lob/LobStringTest.java | 227 ------------------ .../hibernate/test/lob/LongStringTest.java | 84 ++----- .../NationalizedLobFieldTest.java | 1 + .../collection/StringMapLobTest.java | 2 + .../StringMapNationalizedLobTest.java | 2 + 8 files changed, 21 insertions(+), 345 deletions(-) delete mode 100644 hibernate-core/src/test/java/org/hibernate/test/lob/LobStringTest.java diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQL81Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQL81Dialect.java index 9158bfd684..c0c805996d 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQL81Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQL81Dialect.java @@ -188,7 +188,7 @@ public class PostgreSQL81Dialect extends Dialect { break; } case Types.CLOB: { - descriptor = ClobTypeDescriptor.POSTGRESQL_CLOB_BINDING; + descriptor = ClobTypeDescriptor.CLOB_BINDING; break; } default: { diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ClobTypeDescriptor.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ClobTypeDescriptor.java index 703b53d700..5d97cdd9a2 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ClobTypeDescriptor.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ClobTypeDescriptor.java @@ -107,9 +107,6 @@ public class ClobTypeDescriptor extends AbstractTypeDescriptor { : value; return (X) clob; } - else if ( String.class.isAssignableFrom( type ) ) { - return (X) DataHelper.extractString( value.getCharacterStream()); - } } catch ( SQLException e ) { throw new HibernateException( "Unable to access clob stream", e ); @@ -132,9 +129,6 @@ public class ClobTypeDescriptor extends AbstractTypeDescriptor { Reader reader = (Reader) value; return options.getLobCreator().createClob( DataHelper.extractString( reader ) ); } - else if ( String.class.isAssignableFrom( value.getClass() ) ) { - return options.getLobCreator().createClob( (String) value ); - } throw unknownWrap( value.getClass() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/ClobTypeDescriptor.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/ClobTypeDescriptor.java index 72f35dadc1..d07539ec9e 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/ClobTypeDescriptor.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/ClobTypeDescriptor.java @@ -114,48 +114,6 @@ public abstract class ClobTypeDescriptor implements SqlTypeDescriptor { } }; - - public static final ClobTypeDescriptor POSTGRESQL_CLOB_BINDING = new ClobTypeDescriptor() { - @Override - public ValueExtractor getExtractor(JavaTypeDescriptor javaTypeDescriptor) { - return new BasicExtractor( javaTypeDescriptor, this ) { - @Override - protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException { - return javaTypeDescriptor.wrap( rs.getString( name ), options ); - } - - @Override - protected X doExtract(CallableStatement statement, int index, WrapperOptions options) - throws SQLException { - return javaTypeDescriptor.wrap( statement.getString( index ), options ); - } - - @Override - protected X doExtract(CallableStatement statement, String name, WrapperOptions options) - throws SQLException { - return javaTypeDescriptor.wrap( statement.getString( name ), options ); - } - }; - } - - @Override - public BasicBinder getClobBinder(final JavaTypeDescriptor javaTypeDescriptor) { - return new BasicBinder( javaTypeDescriptor, this ) { - @Override - protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options) - throws SQLException { - st.setString( index, javaTypeDescriptor.unwrap( value, String.class, options ) ); - } - - @Override - protected void doBind(CallableStatement st, X value, String name, WrapperOptions options) - throws SQLException { - st.setString( name, javaTypeDescriptor.unwrap( value, String.class, options ) ); - } - }; - } - }; - public static final ClobTypeDescriptor STREAM_BINDING = new ClobTypeDescriptor() { @Override public BasicBinder getClobBinder(final JavaTypeDescriptor javaTypeDescriptor) { diff --git a/hibernate-core/src/test/java/org/hibernate/test/lob/LobStringTest.java b/hibernate-core/src/test/java/org/hibernate/test/lob/LobStringTest.java deleted file mode 100644 index 6147338067..0000000000 --- a/hibernate-core/src/test/java/org/hibernate/test/lob/LobStringTest.java +++ /dev/null @@ -1,227 +0,0 @@ -/* - * 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 . - */ -package org.hibernate.test.lob; - -import java.sql.Clob; -import java.sql.SQLException; -import java.util.List; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.Lob; -import javax.persistence.Table; - -import org.hibernate.dialect.Oracle8iDialect; -import org.hibernate.dialect.SQLServerDialect; -import org.hibernate.engine.jdbc.ClobProxy; -import org.hibernate.query.Query; - -import org.hibernate.testing.SkipForDialect; -import org.hibernate.testing.TestForIssue; -import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; -import org.hibernate.testing.transaction.TransactionUtil; -import org.junit.Test; - -import static org.hamcrest.core.Is.is; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.fail; - -/** - * @author Andrea Boriero - */ -@TestForIssue(jiraKey = "HHH-11477") -@SkipForDialect(Oracle8iDialect.class) -public class LobStringTest extends BaseCoreFunctionalTestCase { - //SQL Server - VARCHAR(MAX) is limited to 8000 bytes only - private static final int LONG_STRING_SIZE = 3999; - - private final String value1 = buildRecursively( LONG_STRING_SIZE, 'x' ); - private final String value2 = buildRecursively( LONG_STRING_SIZE, 'y' ); - - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] {TestEntity.class}; - } - - @Override - protected void prepareTest() throws Exception { - TestEntity entity = new TestEntity(); - TransactionUtil.doInHibernate( this::sessionFactory, session -> { - - entity.setFirstLobField( value1 ); - entity.setSecondLobField( value2 ); - entity.setClobField( session.getLobHelper().createClob( value2 ) ); - session.save( entity ); - } ); - - TransactionUtil.doInHibernate( this::sessionFactory, session -> { - final TestEntity testEntity = session.find( TestEntity.class, entity.getId() ); - assertThat( testEntity.getFirstLobField(), is( value1 ) ); - } ); - } - - @Test - @TestForIssue(jiraKey = "HHH-11477") - public void testHqlQuery() { - TransactionUtil.doInHibernate( this::sessionFactory, session -> { - final Query query = session.createQuery( "from TestEntity" ); - - final List results = query.list(); - - assertThat( results.size(), is( 1 ) ); - - final TestEntity testEntity = results.get( 0 ); - assertThat( testEntity.getFirstLobField(), is( value1 ) ); - assertThat( testEntity.getSecondLobField(), is( value2 ) ); - final Clob clobField = testEntity.getClobField(); - try { - - assertThat( clobField.getSubString( 1, (int) clobField.length() ), is( value2 ) ); - } - catch (SQLException e) { - fail( e.getMessage() ); - } - } ); - } - - @Test - @TestForIssue(jiraKey = "HHH-11477") - public void testUsingStringLobAnnotatedPropertyInHqlQuery() { - TransactionUtil.doInHibernate( this::sessionFactory, session -> { - final Query query = session.createQuery( "from TestEntity where LOWER(firstLobField) LIKE :value" ); - query.setParameter( "value", value1 ); - - final List results = query.list(); - - assertThat( results.size(), is( 1 ) ); - - final TestEntity testEntity = results.get( 0 ); - assertThat( testEntity.getFirstLobField(), is( value1 ) ); - assertThat( testEntity.getSecondLobField(), is( value2 ) ); - final Clob clobField = testEntity.getClobField(); - try { - assertThat( clobField.getSubString( 1, (int) clobField.length() ), is( value2 ) ); - } - catch (SQLException e) { - fail( e.getMessage() ); - } - } ); - } - - @Test - @TestForIssue(jiraKey = "HHH-11477") - public void testSelectStringLobAnnotatedInHqlQuery() { - TransactionUtil.doInHibernate( this::sessionFactory, session -> { - final Query query = session.createQuery( - "select t.secondLobField from TestEntity t where LOWER(t.firstLobField) LIKE :value" ); - query.setParameter( "value", value1 ); - final List results = query.list(); - - assertThat( results.size(), is( 1 ) ); - - assertThat( results.get( 0 ), is( value2 ) ); - } ); - } - - @Test - @TestForIssue(jiraKey = "HHH-11477") - public void testUsingLobPropertyInHqlQuery() { - TransactionUtil.doInHibernate( this::sessionFactory, session -> { - final Query query = session.createQuery( - "select t.secondLobField from TestEntity t where LOWER(t.clobField) LIKE :value" ); - query.setParameter( "value", ClobProxy.generateProxy( value2 ) ); - final List results = query.list(); - - assertThat( results.size(), is( 1 ) ); - - assertThat( results.get( 0 ), is( value2 ) ); - } ); - } - - @Test - @TestForIssue(jiraKey = "HHH-11477") - public void testSelectClobPropertyInHqlQuery() { - TransactionUtil.doInHibernate( this::sessionFactory, session -> { - final Query query = session.createQuery( - "select t.clobField from TestEntity t where LOWER(t.clobField) LIKE :value" ); - query.setParameter( "value", ClobProxy.generateProxy( value2 ) ); - final List results = query.list(); - - assertThat( results.size(), is( 1 ) ); - - final Clob clobField = results.get( 0 ); - try { - assertThat( clobField.getSubString( 1, (int) clobField.length() ), is( value2 ) ); - } - catch (SQLException e) { - fail( e.getMessage() ); - } - } ); - } - - @Entity(name = "TestEntity") - @Table(name = "TEST_ENTITY") - public static class TestEntity { - @Id - @GeneratedValue - private long id; - - @Lob - @Column(length = LONG_STRING_SIZE) //needed by HSQLDialect - String firstLobField; - - @Lob - @Column(length = LONG_STRING_SIZE) //needed by HSQLDialect - String secondLobField; - - @Lob - @Column(length = LONG_STRING_SIZE) //needed by HSQLDialect - Clob clobField; - - public long getId() { - return id; - } - - public String getFirstLobField() { - return firstLobField; - } - - public void setFirstLobField(String firstLobField) { - this.firstLobField = firstLobField; - } - - public String getSecondLobField() { - return secondLobField; - } - - public void setSecondLobField(String secondLobField) { - this.secondLobField = secondLobField; - } - - public Clob getClobField() { - return clobField; - } - - public void setClobField(Clob clobField) { - this.clobField = clobField; - } - } - - @Override - protected boolean isCleanupTestDataRequired() { - return true; - } - - private String buildRecursively(int size, char baseChar) { - StringBuilder buff = new StringBuilder(); - for ( int i = 0; i < size; i++ ) { - buff.append( baseChar ); - } - return buff.toString(); - } -} diff --git a/hibernate-core/src/test/java/org/hibernate/test/lob/LongStringTest.java b/hibernate-core/src/test/java/org/hibernate/test/lob/LongStringTest.java index 0442ae075c..51380d658c 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/lob/LongStringTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/lob/LongStringTest.java @@ -5,24 +5,15 @@ * See the lgpl.txt file in the root directory or . */ package org.hibernate.test.lob; -import java.util.List; - import org.junit.Test; import org.hibernate.Session; -import org.hibernate.dialect.Oracle8iDialect; import org.hibernate.dialect.SybaseASE15Dialect; -import org.hibernate.query.Query; -import org.hibernate.testing.SkipForDialect; -import org.hibernate.testing.TestForIssue; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; -import org.hibernate.testing.transaction.TransactionUtil; -import static org.hamcrest.core.Is.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; /** * Tests eager materialization and mutation of long strings. @@ -32,13 +23,13 @@ import static org.junit.Assert.assertThat; @SuppressWarnings( {"UnusedDeclaration"}) public abstract class LongStringTest extends BaseCoreFunctionalTestCase { private static final int LONG_STRING_SIZE = 10000; - private static final String EMPTY = ""; - - private final String original = buildRecursively( LONG_STRING_SIZE, 'x' ); - private final String changed = buildRecursively( LONG_STRING_SIZE, 'y' ); @Test public void testBoundedLongStringAccess() { + String original = buildRecursively( LONG_STRING_SIZE, 'x' ); + String changed = buildRecursively( LONG_STRING_SIZE, 'y' ); + String empty = ""; + Session s = openSession(); s.beginTransaction(); LongStringHolder entity = new LongStringHolder(); @@ -48,7 +39,7 @@ public abstract class LongStringTest extends BaseCoreFunctionalTestCase { s = openSession(); s.beginTransaction(); - entity = s.get( LongStringHolder.class, entity.getId() ); + entity = ( LongStringHolder ) s.get( LongStringHolder.class, entity.getId() ); assertNull( entity.getLongString() ); entity.setLongString( original ); s.getTransaction().commit(); @@ -56,7 +47,7 @@ public abstract class LongStringTest extends BaseCoreFunctionalTestCase { s = openSession(); s.beginTransaction(); - entity = s.get( LongStringHolder.class, entity.getId() ); + entity = ( LongStringHolder ) s.get( LongStringHolder.class, entity.getId() ); assertEquals( LONG_STRING_SIZE, entity.getLongString().length() ); assertEquals( original, entity.getLongString() ); entity.setLongString( changed ); @@ -65,7 +56,7 @@ public abstract class LongStringTest extends BaseCoreFunctionalTestCase { s = openSession(); s.beginTransaction(); - entity = s.get( LongStringHolder.class, entity.getId() ); + entity = ( LongStringHolder ) s.get( LongStringHolder.class, entity.getId() ); assertEquals( LONG_STRING_SIZE, entity.getLongString().length() ); assertEquals( changed, entity.getLongString() ); entity.setLongString( null ); @@ -74,23 +65,23 @@ public abstract class LongStringTest extends BaseCoreFunctionalTestCase { s = openSession(); s.beginTransaction(); - entity = s.get( LongStringHolder.class, entity.getId() ); + entity = ( LongStringHolder ) s.get( LongStringHolder.class, entity.getId() ); assertNull( entity.getLongString() ); - entity.setLongString( EMPTY ); + entity.setLongString( empty ); s.getTransaction().commit(); s.close(); s = openSession(); s.beginTransaction(); - entity = s.get( LongStringHolder.class, entity.getId() ); + entity = ( LongStringHolder ) s.get( LongStringHolder.class, entity.getId() ); if ( entity.getLongString() != null ) { if(getDialect() instanceof SybaseASE15Dialect){ - //Sybase uses a single blank to denote an EMPTY string (this is by design). So, when inserting an EMPTY string '', it is interpreted as single blank ' '. - assertEquals( EMPTY.length(), entity.getLongString().trim().length() ); - assertEquals( EMPTY, entity.getLongString().trim() ); + //Sybase uses a single blank to denote an empty string (this is by design). So, when inserting an empty string '', it is interpreted as single blank ' '. + assertEquals( empty.length(), entity.getLongString().trim().length() ); + assertEquals( empty, entity.getLongString().trim() ); }else{ - assertEquals( EMPTY.length(), entity.getLongString().length() ); - assertEquals( EMPTY, entity.getLongString() ); + assertEquals( empty.length(), entity.getLongString().length() ); + assertEquals( empty, entity.getLongString() ); } } s.delete( entity ); @@ -98,51 +89,6 @@ public abstract class LongStringTest extends BaseCoreFunctionalTestCase { s.close(); } - @Test - @SkipForDialect(Oracle8iDialect.class) - @TestForIssue( jiraKey = "HHH-11477") - public void testUsingLobPropertyInHqlQuery() { - TransactionUtil.doInHibernate( this::sessionFactory, session -> { - LongStringHolder entity = new LongStringHolder(); - entity.setLongString( original ); - session.save( entity ); - } ); - - TransactionUtil.doInHibernate( this::sessionFactory, session -> { - final Query query = session.createQuery( "from LongStringHolder where longString = :stringValue" ); - query.setParameter( "stringValue", original ); - final List results = query.list(); - assertThat( results.size(), is( 1 ) ); - - assertThat( results.get( 0 ).getLongString(), is( original ) ); - } ); - } - - @Test - @SkipForDialect(Oracle8iDialect.class) - @TestForIssue( jiraKey = "HHH-11477") - public void testSelectLobPropertyInHqlQuery() { - TransactionUtil.doInHibernate( this::sessionFactory, session -> { - LongStringHolder entity = new LongStringHolder(); - entity.setLongString( original ); - session.save( entity ); - } ); - - TransactionUtil.doInHibernate( this::sessionFactory, session -> { - final Query query = session.createQuery( "select l.longString from LongStringHolder l where l.longString = :stringValue" ); - query.setParameter( "stringValue", original ); - final List results = query.list(); - assertThat( results.size(), is( 1 ) ); - - assertThat( results.get( 0 ), is( original ) ); - } ); - } - - @Override - protected boolean isCleanupTestDataRequired() { - return true; - } - private String buildRecursively(int size, char baseChar) { StringBuilder buff = new StringBuilder(); for( int i = 0; i < size; i++ ) { diff --git a/hibernate-core/src/test/java/org/hibernate/test/nationalized/NationalizedLobFieldTest.java b/hibernate-core/src/test/java/org/hibernate/test/nationalized/NationalizedLobFieldTest.java index 9e7b15cb90..fbabab6937 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/nationalized/NationalizedLobFieldTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/nationalized/NationalizedLobFieldTest.java @@ -37,6 +37,7 @@ import static org.junit.Assert.assertThat; @TestForIssue(jiraKey = "HHH-10364") @SkipForDialect(value = DB2Dialect.class, comment = "DB2 jdbc driver doesn't support getNClob") @SkipForDialect(value = MySQLDialect.class, comment = "MySQL/MariadB doesn't support nclob") +@SkipForDialect(value = PostgreSQL81Dialect.class, comment = "PostgreSQL doesn't support nclob") @SkipForDialect(value = SybaseDialect.class, comment = "Sybase doesn't support nclob") public class NationalizedLobFieldTest extends BaseCoreFunctionalTestCase { diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/collection/StringMapLobTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/collection/StringMapLobTest.java index 6342fe6192..b3eb9955e1 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/collection/StringMapLobTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/collection/StringMapLobTest.java @@ -16,6 +16,7 @@ import javax.persistence.Id; import javax.persistence.Lob; import org.hibernate.dialect.Oracle8iDialect; +import org.hibernate.dialect.PostgreSQL81Dialect; import org.hibernate.envers.Audited; import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; @@ -33,6 +34,7 @@ import static org.junit.Assert.assertEquals; */ @TestForIssue(jiraKey = "HHH-9834") @SkipForDialect(Oracle8iDialect.class) +@SkipForDialect(value = PostgreSQL81Dialect.class, jiraKey = "HHH-11477", comment = "@Lob field in HQL predicate fails with error about text = bigint") public class StringMapLobTest extends BaseEnversJPAFunctionalTestCase { @Override protected Class[] getAnnotatedClasses() { diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/collection/StringMapNationalizedLobTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/collection/StringMapNationalizedLobTest.java index 7f13ddadc9..6fb0cae3a9 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/collection/StringMapNationalizedLobTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/collection/StringMapNationalizedLobTest.java @@ -17,6 +17,7 @@ import javax.persistence.Lob; import org.hibernate.annotations.Nationalized; import org.hibernate.dialect.Oracle8iDialect; +import org.hibernate.dialect.PostgreSQL81Dialect; import org.hibernate.envers.Audited; import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase; import org.hibernate.envers.test.Priority; @@ -34,6 +35,7 @@ import static org.junit.Assert.assertEquals; */ @TestForIssue(jiraKey = "HHH-9834") @SkipForDialect(Oracle8iDialect.class) +@SkipForDialect(value = PostgreSQL81Dialect.class, jiraKey = "HHH-11477", comment = "@Lob field in HQL predicate fails with error about text = bigint") public class StringMapNationalizedLobTest extends BaseEnversJPAFunctionalTestCase { @Override protected Class[] getAnnotatedClasses() {