Re-enabled additional tests
This commit is contained in:
parent
6745f71f88
commit
67c2c51d47
|
@ -9,17 +9,19 @@ package org.hibernate.orm.test.lob;
|
|||
import java.sql.Clob;
|
||||
|
||||
import org.hibernate.LockOptions;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.dialect.SybaseASEDialect;
|
||||
import org.hibernate.type.descriptor.java.DataHelper;
|
||||
|
||||
import org.hibernate.testing.DialectChecks;
|
||||
import org.hibernate.testing.RequiresDialectFeature;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
/**
|
||||
* Tests lazy materialization of data mapped by
|
||||
|
@ -29,133 +31,176 @@ import static org.junit.Assert.assertNotNull;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
@RequiresDialectFeature(
|
||||
value = { DialectChecks.SupportsExpectedLobUsagePattern.class, DialectChecks.SupportsUnboundedLobLocatorMaterializationCheck.class },
|
||||
feature = DialectFeatureChecks.SupportsExpectedLobUsagePattern.class,
|
||||
comment = "database/driver does not support expected LOB usage pattern"
|
||||
)
|
||||
public class ClobLocatorTest extends BaseCoreFunctionalTestCase {
|
||||
@RequiresDialectFeature(
|
||||
feature = DialectFeatureChecks.SupportsUnboundedLobLocatorMaterializationCheck.class,
|
||||
comment = "database/driver does not support expected LOB usage pattern"
|
||||
)
|
||||
@DomainModel(
|
||||
xmlMappings = "org/hibernate/orm/test/lob/LobMappings.hbm.xml"
|
||||
)
|
||||
@SessionFactory
|
||||
public class ClobLocatorTest {
|
||||
private static final int CLOB_SIZE = 10000;
|
||||
|
||||
@Override
|
||||
protected String getBaseForMappings() {
|
||||
return "org/hibernate/orm/test/";
|
||||
}
|
||||
|
||||
public String[] getMappings() {
|
||||
return new String[] { "lob/LobMappings.hbm.xml" };
|
||||
return new String[] { "" };
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBoundedClobLocatorAccess() throws Throwable {
|
||||
public void testBoundedClobLocatorAccess(SessionFactoryScope scope) throws Throwable {
|
||||
String original = buildString( CLOB_SIZE, 'x' );
|
||||
String changed = buildString( CLOB_SIZE, 'y' );
|
||||
String empty = "";
|
||||
|
||||
Session s = openSession();
|
||||
s.beginTransaction();
|
||||
LobHolder entity = new LobHolder();
|
||||
entity.setClobLocator( s.getLobHelper().createClob( original ) );
|
||||
s.save( entity );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
Long id = scope.fromTransaction(
|
||||
session -> {
|
||||
LobHolder entity = new LobHolder();
|
||||
entity.setClobLocator( session.getLobHelper().createClob( original ) );
|
||||
session.save( entity );
|
||||
return entity.getId();
|
||||
}
|
||||
);
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
entity = s.get( LobHolder.class, entity.getId() );
|
||||
assertEquals( CLOB_SIZE, entity.getClobLocator().length() );
|
||||
assertEquals( original, extractData( entity.getClobLocator() ) );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
try {
|
||||
LobHolder entity = session.get( LobHolder.class, id );
|
||||
assertEquals( CLOB_SIZE, entity.getClobLocator().length() );
|
||||
assertEquals( original, extractData( entity.getClobLocator() ) );
|
||||
}
|
||||
catch (Exception e) {
|
||||
fail( e );
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// test mutation via setting the new clob data...
|
||||
if ( getDialect().supportsLobValueChangePropagation() ) {
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
entity = ( LobHolder ) s.byId( LobHolder.class ).with( LockOptions.UPGRADE ).load( entity.getId() );
|
||||
entity.getClobLocator().truncate( 1 );
|
||||
entity.getClobLocator().setString( 1, changed );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
if ( scope.getSessionFactory().getJdbcServices().getDialect().supportsLobValueChangePropagation() ) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
try {
|
||||
LobHolder entity = session.byId( LobHolder.class )
|
||||
.with( LockOptions.UPGRADE )
|
||||
.load( id );
|
||||
entity.getClobLocator().truncate( 1 );
|
||||
entity.getClobLocator().setString( 1, changed );
|
||||
}
|
||||
catch (Exception e) {
|
||||
fail( e );
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
entity = ( LobHolder ) s.byId( LobHolder.class ).with( LockOptions.UPGRADE ).load( entity.getId() );
|
||||
assertNotNull( entity.getClobLocator() );
|
||||
assertEquals( CLOB_SIZE, entity.getClobLocator().length() );
|
||||
assertEquals( changed, extractData( entity.getClobLocator() ) );
|
||||
entity.getClobLocator().truncate( 1 );
|
||||
entity.getClobLocator().setString( 1, original );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
try {
|
||||
LobHolder entity = session.byId( LobHolder.class )
|
||||
.with( LockOptions.UPGRADE )
|
||||
.load( id );
|
||||
assertNotNull( entity.getClobLocator() );
|
||||
|
||||
assertEquals( CLOB_SIZE, entity.getClobLocator().length() );
|
||||
|
||||
assertEquals( changed, extractData( entity.getClobLocator() ) );
|
||||
entity.getClobLocator().truncate( 1 );
|
||||
entity.getClobLocator().setString( 1, original );
|
||||
}
|
||||
catch (Exception e) {
|
||||
fail( e );
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// test mutation via supplying a new clob locator instance...
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
entity = ( LobHolder ) s.byId( LobHolder.class ).with( LockOptions.UPGRADE ).load( entity.getId() );
|
||||
assertNotNull( entity.getClobLocator() );
|
||||
assertEquals( CLOB_SIZE, entity.getClobLocator().length() );
|
||||
assertEquals( original, extractData( entity.getClobLocator() ) );
|
||||
entity.setClobLocator( s.getLobHelper().createClob( changed ) );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
try {
|
||||
LobHolder entity = session.byId( LobHolder.class ).with( LockOptions.UPGRADE ).load( id );
|
||||
assertNotNull( entity.getClobLocator() );
|
||||
assertEquals( CLOB_SIZE, entity.getClobLocator().length() );
|
||||
assertEquals( original, extractData( entity.getClobLocator() ) );
|
||||
entity.setClobLocator( session.getLobHelper().createClob( changed ) );
|
||||
}
|
||||
catch (Exception e) {
|
||||
fail( e );
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// test empty clob
|
||||
if ( !(getDialect() instanceof SybaseASEDialect ) ) { // Skip for Sybase. HHH-6425
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
entity = s.get( LobHolder.class, entity.getId() );
|
||||
assertEquals( CLOB_SIZE, entity.getClobLocator().length() );
|
||||
assertEquals( changed, extractData( entity.getClobLocator() ) );
|
||||
entity.setClobLocator( s.getLobHelper().createClob( empty ) );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
if ( !( scope.getSessionFactory()
|
||||
.getJdbcServices()
|
||||
.getDialect() instanceof SybaseASEDialect ) ) { // Skip for Sybase. HHH-6425
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
try {
|
||||
LobHolder entity = session.get( LobHolder.class, id );
|
||||
assertEquals( CLOB_SIZE, entity.getClobLocator().length() );
|
||||
assertEquals( changed, extractData( entity.getClobLocator() ) );
|
||||
entity.setClobLocator( session.getLobHelper().createClob( empty ) );
|
||||
}
|
||||
catch (Exception e) {
|
||||
fail( e );
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
entity = s.get( LobHolder.class, entity.getId() );
|
||||
if ( entity.getClobLocator() != null) {
|
||||
assertEquals( empty.length(), entity.getClobLocator().length() );
|
||||
assertEquals( empty, extractData( entity.getClobLocator() ) );
|
||||
}
|
||||
s.delete( entity );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
try {
|
||||
LobHolder entity = session.get( LobHolder.class, id );
|
||||
if ( entity.getClobLocator() != null ) {
|
||||
assertEquals( empty.length(), entity.getClobLocator().length() );
|
||||
assertEquals( empty, extractData( entity.getClobLocator() ) );
|
||||
}
|
||||
session.delete( entity );
|
||||
}
|
||||
catch (Exception e) {
|
||||
fail( e );
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnboundedClobLocatorAccess() throws Throwable {
|
||||
public void testUnboundedClobLocatorAccess(SessionFactoryScope scope) throws Throwable {
|
||||
// Note: unbounded mutation of the underlying lob data is completely
|
||||
// unsupported; most databases would not allow such a construct anyway.
|
||||
// Thus here we are only testing materialization...
|
||||
|
||||
String original = buildString( CLOB_SIZE, 'x' );
|
||||
|
||||
Session s = openSession();
|
||||
s.beginTransaction();
|
||||
LobHolder entity = new LobHolder();
|
||||
entity.setClobLocator( s.getLobHelper().createClob( original ) );
|
||||
s.save( entity );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
Long id = scope.fromTransaction(
|
||||
session -> {
|
||||
LobHolder entity = new LobHolder();
|
||||
entity.setClobLocator( session.getLobHelper().createClob( original ) );
|
||||
session.save( entity );
|
||||
return entity.getId();
|
||||
}
|
||||
);
|
||||
|
||||
// load the entity with the clob locator, and close the session/transaction;
|
||||
// at that point it is unbounded...
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
entity = s.get( LobHolder.class, entity.getId() );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
LobHolder lobHolder = scope.fromTransaction(
|
||||
session ->
|
||||
session.get( LobHolder.class, id )
|
||||
|
||||
assertEquals( CLOB_SIZE, entity.getClobLocator().length() );
|
||||
assertEquals( original, extractData( entity.getClobLocator() ) );
|
||||
);
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
s.delete( entity );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
assertEquals( CLOB_SIZE, lobHolder.getClobLocator().length() );
|
||||
assertEquals( original, extractData( lobHolder.getClobLocator() ) );
|
||||
|
||||
scope.inTransaction(
|
||||
session ->
|
||||
session.delete( lobHolder )
|
||||
);
|
||||
}
|
||||
|
||||
public static String extractData(Clob clob) throws Exception {
|
||||
|
@ -164,7 +209,7 @@ public class ClobLocatorTest extends BaseCoreFunctionalTestCase {
|
|||
|
||||
public static String buildString(int size, char baseChar) {
|
||||
StringBuilder buff = new StringBuilder();
|
||||
for( int i = 0; i < size; i++ ) {
|
||||
for ( int i = 0; i < size; i++ ) {
|
||||
buff.append( baseChar );
|
||||
}
|
||||
return buff.toString();
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
|
||||
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
|
||||
|
||||
<hibernate-mapping package="org.hibernate.test.lob">
|
||||
<hibernate-mapping package="org.hibernate.orm.test.lob">
|
||||
|
||||
<class name="LongByteArrayHolder" table="LOB_ENTITY_IMAGE">
|
||||
<id name="id" type="long" column="ID">
|
|
@ -4,7 +4,9 @@
|
|||
* 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.lob;
|
||||
package org.hibernate.orm.test.lob;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
|
||||
/**
|
||||
* Tests eager materialization and mutation of data mapped by
|
||||
|
@ -12,8 +14,8 @@ package org.hibernate.test.lob;
|
|||
*
|
||||
* @author Gail Badner
|
||||
*/
|
||||
@DomainModel(
|
||||
xmlMappings = "org/hibernate/orm/test/lob/ImageMappings.hbm.xml"
|
||||
)
|
||||
public class ImageTest extends LongByteArrayTest {
|
||||
public String[] getMappings() {
|
||||
return new String[] { "lob/ImageMappings.hbm.xml" };
|
||||
}
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* 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.orm.test.lob;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.sql.Blob;
|
||||
import java.util.Random;
|
||||
|
||||
import org.hibernate.LobHelper;
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.dialect.H2Dialect;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.RequiresDialect;
|
||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.Setting;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Brett Meyer
|
||||
*/
|
||||
@TestForIssue(jiraKey = "HHH-7698")
|
||||
@RequiresDialect(value = H2Dialect.class, comment = "HHH-7724")
|
||||
@DomainModel(
|
||||
annotatedClasses = LobEntity.class
|
||||
)
|
||||
@SessionFactory
|
||||
@ServiceRegistry(
|
||||
settings = @Setting(name = Environment.USE_STREAMS_FOR_BINARY, value = "true")
|
||||
)
|
||||
public class JpaLargeBlobTest {
|
||||
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] { LobEntity.class };
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jpaBlobStream(SessionFactoryScope scope) throws Exception {
|
||||
LobEntity o = new LobEntity();
|
||||
LobInputStream inputStream = scope.fromSession(
|
||||
session -> {
|
||||
LobHelper lh = session.getLobHelper();
|
||||
LobInputStream lis = new LobInputStream();
|
||||
|
||||
session.getTransaction().begin();
|
||||
try {
|
||||
Blob blob = lh.createBlob( lis, LobEntity.BLOB_LENGTH );
|
||||
o.setBlob( blob );
|
||||
|
||||
// Regardless if NON_CONTEXTUAL_LOB_CREATION is set to true,
|
||||
// ContextualLobCreator should use a NonContextualLobCreator to create
|
||||
// a blob Proxy. If that's the case, the InputStream will not be read
|
||||
// until it's persisted with the JDBC driver.
|
||||
// Although HHH-7698 was about high memory consumption, this is the best
|
||||
// way to test that the high memory use is being prevented.
|
||||
assertFalse( lis.wasRead() );
|
||||
|
||||
session.persist( o );
|
||||
session.getTransaction().commit();
|
||||
}
|
||||
catch (Exception e) {
|
||||
if ( session.getTransaction().isActive() ) {
|
||||
session.getTransaction().rollback();
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
assertTrue( lis.wasRead() );
|
||||
return lis;
|
||||
}
|
||||
);
|
||||
inputStream.close();
|
||||
}
|
||||
|
||||
private class LobInputStream extends InputStream {
|
||||
private boolean read = false;
|
||||
private Long count = (long) 200 * 1024 * 1024;
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
read = true;
|
||||
if ( count > 0 ) {
|
||||
count--;
|
||||
return new Random().nextInt();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public boolean wasRead() {
|
||||
return read;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,7 +9,7 @@
|
|||
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
|
||||
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
|
||||
|
||||
<hibernate-mapping package="org.hibernate.test.lob">
|
||||
<hibernate-mapping package="org.hibernate.orm.test.lob">
|
||||
|
||||
<class name="LobAsLastValueEntity">
|
||||
<id name="id" type="integer">
|
|
@ -4,7 +4,7 @@
|
|||
* 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.lob;
|
||||
package org.hibernate.orm.test.lob;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
|
@ -4,33 +4,32 @@
|
|||
* 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.lob;
|
||||
package org.hibernate.orm.test.lob;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.testing.DialectChecks;
|
||||
import org.hibernate.testing.RequiresDialectFeature;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
||||
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* @author Chris Cranford
|
||||
*/
|
||||
@RequiresDialectFeature(DialectChecks.ForceLobAsLastValue.class)
|
||||
@RequiresDialectFeature(feature = DialectFeatureChecks.ForceLobAsLastValue.class)
|
||||
@TestForIssue(jiraKey = "HHH-8382")
|
||||
public class LobAsLastValueTest extends BaseCoreFunctionalTestCase {
|
||||
@Override
|
||||
protected String[] getMappings() {
|
||||
return new String[] { "lob/LobAsLastValue.hbm.xml" };
|
||||
}
|
||||
@DomainModel(
|
||||
xmlMappings = "org/hibernate/orm/test/lob/LobAsLastValue.hbm.xml"
|
||||
)
|
||||
@SessionFactory
|
||||
public class LobAsLastValueTest {
|
||||
|
||||
@Test
|
||||
public void testInsertLobAsLastValue() {
|
||||
doInHibernate( this::sessionFactory, session -> {
|
||||
public void testInsertLobAsLastValue(SessionFactoryScope scope) {
|
||||
scope.inTransaction( session -> {
|
||||
byte[] details = new byte[4000];
|
||||
byte[] title = new byte[2000];
|
||||
|
||||
|
@ -40,7 +39,11 @@ public class LobAsLastValueTest extends BaseCoreFunctionalTestCase {
|
|||
|
||||
// This insert will fail on Oracle without the fix to ModelBinder flagging SimpleValue and Property as Lob
|
||||
// because the fields will not be placed at the end of the insert, resulting in an Oracle failure.
|
||||
final LobAsLastValueEntity entity = new LobAsLastValueEntity( "Test", new String( details ), new String( title ) );
|
||||
final LobAsLastValueEntity entity = new LobAsLastValueEntity(
|
||||
"Test",
|
||||
new String( details ),
|
||||
new String( title )
|
||||
);
|
||||
session.save( entity );
|
||||
} );
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
* 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.lob;
|
||||
package org.hibernate.orm.test.lob;
|
||||
|
||||
import java.sql.Blob;
|
||||
|
|
@ -0,0 +1,248 @@
|
|||
/*
|
||||
* 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.orm.test.lob;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.sql.Clob;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.dialect.CockroachDialect;
|
||||
import org.hibernate.dialect.PostgreSQLDialect;
|
||||
import org.hibernate.query.Query;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.RequiresDialect;
|
||||
import org.hibernate.testing.orm.junit.RequiresDialects;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Lob;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
@TestForIssue(jiraKey = "HHH-11477")
|
||||
@RequiresDialects({ @RequiresDialect(PostgreSQLDialect.class), @RequiresDialect(CockroachDialect.class) })
|
||||
@DomainModel(
|
||||
annotatedClasses = LobStringTest.TestEntity.class
|
||||
)
|
||||
@SessionFactory
|
||||
public class LobStringTest {
|
||||
|
||||
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' );
|
||||
|
||||
@BeforeEach
|
||||
protected void prepareTest(SessionFactoryScope scope) throws Exception {
|
||||
TestEntity entity = new TestEntity();
|
||||
scope.inTransaction( session -> {
|
||||
|
||||
entity.setFirstLobField( value1 );
|
||||
entity.setSecondLobField( value2 );
|
||||
entity.setClobField( session.getLobHelper().createClob( value2 ) );
|
||||
session.save( entity );
|
||||
} );
|
||||
|
||||
scope.inTransaction( session -> {
|
||||
final TestEntity testEntity = session.find( TestEntity.class, entity.getId() );
|
||||
assertThat( testEntity.getFirstLobField(), is( value1 ) );
|
||||
} );
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void tearDown(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session ->
|
||||
session.createQuery( "delete from TestEntity" ).executeUpdate()
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-11477")
|
||||
public void testHqlQuery(SessionFactoryScope scope) {
|
||||
scope.inTransaction( session -> {
|
||||
final Query query = session.createQuery( "from TestEntity" );
|
||||
|
||||
final List<TestEntity> 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")
|
||||
@RequiresDialect(PostgreSQLDialect.class)
|
||||
public void testUsingStringLobAnnotatedPropertyInNativeQuery(SessionFactoryScope scope) {
|
||||
scope.inTransaction( session -> {
|
||||
final List<TestEntity> results = session.createNativeQuery(
|
||||
"select te.* " +
|
||||
"from test_entity te " +
|
||||
"where lower(convert_from(lo_get(cast(te.firstLobField as oid)), 'UTF8')) LIKE :value",
|
||||
TestEntity.class
|
||||
)
|
||||
.setParameter( "value", value1 )
|
||||
.getResultList();
|
||||
|
||||
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")
|
||||
@RequiresDialect(PostgreSQLDialect.class)
|
||||
public void testSelectStringLobAnnotatedInNativeQuery(SessionFactoryScope scope) {
|
||||
scope.inTransaction( session -> {
|
||||
final List<String> results = session.createNativeQuery(
|
||||
"select convert_from(lo_get(cast(te.secondLobField as oid)), 'UTF8') " +
|
||||
"from test_entity te " +
|
||||
"where lower(convert_from(lo_get(cast(te.firstLobField as oid)), 'UTF8')) LIKE :value" )
|
||||
.setParameter( "value", value1 )
|
||||
.list();
|
||||
|
||||
assertThat( results.size(), is( 1 ) );
|
||||
|
||||
assertThat( results.get( 0 ), is( value2 ) );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-11477")
|
||||
@RequiresDialect(PostgreSQLDialect.class)
|
||||
public void testUsingLobPropertyInNativeQuery(SessionFactoryScope scope) {
|
||||
scope.inTransaction( session -> {
|
||||
final List<String> results = session.createNativeQuery(
|
||||
"select convert_from(lo_get(cast(te.secondLobField as oid)), 'UTF8') " +
|
||||
"from test_entity te " +
|
||||
"where lower(convert_from(lo_get(cast(te.clobField as oid)), 'UTF8')) LIKE :value" )
|
||||
.setParameter( "value", value2 )
|
||||
.list();
|
||||
|
||||
assertThat( results.size(), is( 1 ) );
|
||||
|
||||
assertThat( results.get( 0 ), is( value2 ) );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-11477")
|
||||
@RequiresDialect(PostgreSQLDialect.class)
|
||||
public void testSelectClobPropertyInNativeQuery(SessionFactoryScope scope) {
|
||||
scope.inTransaction( session -> {
|
||||
final List<byte[]> results = session.createNativeQuery(
|
||||
"select lo_get(cast(te.clobField as oid)) " +
|
||||
"from test_entity te " +
|
||||
"where lower(convert_from(lo_get(cast(te.clobField as oid)), 'UTF8')) LIKE :value" )
|
||||
.setParameter( "value", value2 )
|
||||
.list();
|
||||
|
||||
assertThat( results.size(), is( 1 ) );
|
||||
|
||||
try {
|
||||
assertThat( new String( results.get( 0 ), "UTF8" ), is( value2 ) );
|
||||
}
|
||||
catch (UnsupportedEncodingException 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private String buildRecursively(int size, char baseChar) {
|
||||
StringBuilder buff = new StringBuilder();
|
||||
for ( int i = 0; i < size; i++ ) {
|
||||
buff.append( baseChar );
|
||||
}
|
||||
return buff.toString();
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
//$Id: $
|
||||
|
||||
package org.hibernate.test.lob;
|
||||
package org.hibernate.orm.test.lob;
|
||||
|
||||
|
||||
/**
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* 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.orm.test.lob;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.hibernate.dialect.SybaseASEDialect;
|
||||
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.SkipForDialect;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
|
||||
/**
|
||||
* Tests eager materialization and mutation of long byte arrays.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@SessionFactory
|
||||
public abstract class LongByteArrayTest {
|
||||
private static final int ARRAY_SIZE = 10000;
|
||||
|
||||
@Test
|
||||
public void testBoundedLongByteArrayAccess(SessionFactoryScope scope) {
|
||||
byte[] original = buildRecursively( ARRAY_SIZE, true );
|
||||
byte[] changed = buildRecursively( ARRAY_SIZE, false );
|
||||
byte[] empty = new byte[] {};
|
||||
|
||||
Long id = scope.fromTransaction(
|
||||
session -> {
|
||||
LongByteArrayHolder entity = new LongByteArrayHolder();
|
||||
session.save( entity );
|
||||
return entity.getId();
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
LongByteArrayHolder entity = session.get( LongByteArrayHolder.class, id );
|
||||
assertNull( entity.getLongByteArray() );
|
||||
entity.setLongByteArray( original );
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
LongByteArrayHolder entity = session.get( LongByteArrayHolder.class, id );
|
||||
Assertions.assertEquals( ARRAY_SIZE, entity.getLongByteArray().length );
|
||||
assertEquals( original, entity.getLongByteArray() );
|
||||
entity.setLongByteArray( changed );
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
LongByteArrayHolder entity = session.get( LongByteArrayHolder.class, id );
|
||||
Assertions.assertEquals( ARRAY_SIZE, entity.getLongByteArray().length );
|
||||
assertEquals( changed, entity.getLongByteArray() );
|
||||
entity.setLongByteArray( null );
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
LongByteArrayHolder entity = session.get( LongByteArrayHolder.class, id );
|
||||
assertNull( entity.getLongByteArray() );
|
||||
entity.setLongByteArray( empty );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SkipForDialect(dialectClass = SybaseASEDialect.class, reason = "Sybase returns byte[]{0}")
|
||||
public void testEmptyArray(SessionFactoryScope scope) {
|
||||
byte[] empty = new byte[] {};
|
||||
|
||||
LongByteArrayHolder longByteArrayHolder = new LongByteArrayHolder();
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
longByteArrayHolder.setLongByteArray( empty );
|
||||
session.save( longByteArrayHolder );
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
LongByteArrayHolder entity = session.get( LongByteArrayHolder.class, longByteArrayHolder.getId() );
|
||||
if ( entity.getLongByteArray() != null ) {
|
||||
Assertions.assertEquals( empty.length, entity.getLongByteArray().length );
|
||||
assertEquals( empty, entity.getLongByteArray() );
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSaving(SessionFactoryScope scope) {
|
||||
byte[] value = buildRecursively( ARRAY_SIZE, true );
|
||||
|
||||
Long id = scope.fromTransaction(
|
||||
session -> {
|
||||
LongByteArrayHolder entity = new LongByteArrayHolder();
|
||||
entity.setLongByteArray( value );
|
||||
session.persist( entity );
|
||||
return entity.getId();
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
LongByteArrayHolder entity = session.get( LongByteArrayHolder.class, id );
|
||||
Assertions.assertEquals( ARRAY_SIZE, entity.getLongByteArray().length );
|
||||
assertEquals( value, entity.getLongByteArray() );
|
||||
session.delete( entity );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void tearDown(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session ->
|
||||
session.createQuery( "delete from LongByteArrayHolder" ).executeUpdate()
|
||||
);
|
||||
}
|
||||
|
||||
private byte[] buildRecursively(int size, boolean on) {
|
||||
byte[] data = new byte[size];
|
||||
data[0] = mask( on );
|
||||
for ( int i = 0; i < size; i++ ) {
|
||||
data[i] = mask( on );
|
||||
on = !on;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
private byte mask(boolean on) {
|
||||
return on ? (byte) 1 : (byte) 0;
|
||||
}
|
||||
|
||||
public static void assertEquals(byte[] val1, byte[] val2) {
|
||||
if ( !Arrays.equals( val1, val2 ) ) {
|
||||
fail( "byte arrays did not match" );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
//$Id: $
|
||||
|
||||
package org.hibernate.test.lob;
|
||||
package org.hibernate.orm.test.lob;
|
||||
|
||||
|
||||
/**
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* 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.orm.test.lob;
|
||||
|
||||
|
||||
import org.hibernate.dialect.SybaseASEDialect;
|
||||
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
||||
|
||||
/**
|
||||
* Tests eager materialization and mutation of long strings.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@SuppressWarnings({ "UnusedDeclaration" })
|
||||
@SessionFactory
|
||||
public abstract class LongStringTest {
|
||||
private static final int LONG_STRING_SIZE = 10000;
|
||||
|
||||
@Test
|
||||
public void testBoundedLongStringAccess(SessionFactoryScope scope) {
|
||||
String original = buildRecursively( LONG_STRING_SIZE, 'x' );
|
||||
String changed = buildRecursively( LONG_STRING_SIZE, 'y' );
|
||||
String empty = "";
|
||||
|
||||
Long id = scope.fromTransaction(
|
||||
session -> {
|
||||
LongStringHolder entity = new LongStringHolder();
|
||||
session.save( entity );
|
||||
return entity.getId();
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
LongStringHolder entity = session.get( LongStringHolder.class, id );
|
||||
assertNull( entity.getLongString() );
|
||||
entity.setLongString( original );
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
LongStringHolder entity = session.get( LongStringHolder.class, id );
|
||||
assertEquals( LONG_STRING_SIZE, entity.getLongString().length() );
|
||||
assertEquals( original, entity.getLongString() );
|
||||
entity.setLongString( changed );
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
LongStringHolder entity = session.get( LongStringHolder.class, id );
|
||||
assertEquals( LONG_STRING_SIZE, entity.getLongString().length() );
|
||||
assertEquals( changed, entity.getLongString() );
|
||||
entity.setLongString( null );
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
LongStringHolder entity = session.get( LongStringHolder.class, id );
|
||||
assertNull( entity.getLongString() );
|
||||
entity.setLongString( empty );
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
LongStringHolder entity = session.get( LongStringHolder.class, id );
|
||||
if ( entity.getLongString() != null ) {
|
||||
if ( scope.getSessionFactory().getJdbcServices().getDialect() instanceof SybaseASEDialect ) {
|
||||
//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() );
|
||||
}
|
||||
}
|
||||
session.delete( entity );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private String buildRecursively(int size, char baseChar) {
|
||||
StringBuilder buff = new StringBuilder();
|
||||
for ( int i = 0; i < size; i++ ) {
|
||||
buff.append( baseChar );
|
||||
}
|
||||
return buff.toString();
|
||||
}
|
||||
}
|
|
@ -9,7 +9,7 @@
|
|||
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
|
||||
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
|
||||
|
||||
<hibernate-mapping package="org.hibernate.test.lob">
|
||||
<hibernate-mapping package="org.hibernate.orm.test.lob">
|
||||
|
||||
<class name="LongByteArrayHolder" table="LOB_ENTITY_MAT_BLOB">
|
||||
<id name="id" type="long" column="ID">
|
|
@ -4,10 +4,12 @@
|
|||
* 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.lob;
|
||||
package org.hibernate.orm.test.lob;
|
||||
|
||||
import org.hibernate.testing.DialectChecks;
|
||||
import org.hibernate.testing.RequiresDialectFeature;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
|
||||
|
||||
/**
|
||||
* Tests eager materialization and mutation of data mapped by
|
||||
|
@ -16,11 +18,11 @@ import org.hibernate.testing.RequiresDialectFeature;
|
|||
* @author Gail Badner
|
||||
*/
|
||||
@RequiresDialectFeature(
|
||||
value = DialectChecks.SupportsExpectedLobUsagePattern.class,
|
||||
feature = DialectFeatureChecks.SupportsExpectedLobUsagePattern.class,
|
||||
comment = "database/driver does not support expected LOB usage pattern"
|
||||
)
|
||||
@DomainModel(
|
||||
xmlMappings = "org/hibernate/orm/test/lob/MaterializedBlobMappings.hbm.xml"
|
||||
)
|
||||
public class MaterializedBlobTest extends LongByteArrayTest {
|
||||
public String[] getMappings() {
|
||||
return new String[] { "lob/MaterializedBlobMappings.hbm.xml" };
|
||||
}
|
||||
}
|
|
@ -9,7 +9,7 @@
|
|||
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
|
||||
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
|
||||
|
||||
<hibernate-mapping package="org.hibernate.test.lob">
|
||||
<hibernate-mapping package="org.hibernate.orm.test.lob">
|
||||
|
||||
<class name="LongStringHolder" table="LOB_ENTITY_MAT_CLOB">
|
||||
<id name="id" type="long" column="ID">
|
|
@ -4,10 +4,11 @@
|
|||
* 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.lob;
|
||||
package org.hibernate.orm.test.lob;
|
||||
|
||||
import org.hibernate.testing.DialectChecks;
|
||||
import org.hibernate.testing.RequiresDialectFeature;
|
||||
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
|
||||
|
||||
/**
|
||||
* Tests eager materialization and mutation of data mapped by
|
||||
|
@ -15,9 +16,9 @@ import org.hibernate.testing.RequiresDialectFeature;
|
|||
*
|
||||
* @author Gail Badner
|
||||
*/
|
||||
@RequiresDialectFeature( DialectChecks.SupportsExpectedLobUsagePattern.class )
|
||||
@RequiresDialectFeature(feature = DialectFeatureChecks.SupportsExpectedLobUsagePattern.class)
|
||||
@DomainModel(
|
||||
xmlMappings = "org/hibernate/orm/test/lob/MaterializedClobMappings.hbm.xml"
|
||||
)
|
||||
public class MaterializedClobTest extends LongStringTest {
|
||||
public String[] getMappings() {
|
||||
return new String[] { "lob/MaterializedClobMappings.hbm.xml" };
|
||||
}
|
||||
}
|
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
* 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.orm.test.lob;
|
||||
|
||||
import java.sql.Clob;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.dialect.PostgreSQLDialect;
|
||||
import org.hibernate.query.Query;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.RequiresDialect;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.testing.util.ExceptionUtil;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Lob;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
@TestForIssue(jiraKey = "HHH-11614")
|
||||
@RequiresDialect(PostgreSQLDialect.class)
|
||||
@DomainModel(
|
||||
annotatedClasses = PostgreSqlLobStringTest.TestEntity.class
|
||||
)
|
||||
@SessionFactory
|
||||
public class PostgreSqlLobStringTest {
|
||||
|
||||
private final String value1 = "abc";
|
||||
private final String value2 = "def";
|
||||
private final String value3 = "ghi";
|
||||
|
||||
@BeforeEach
|
||||
protected void prepareTest(SessionFactoryScope scope)
|
||||
throws Exception {
|
||||
|
||||
scope.inTransaction(
|
||||
session ->
|
||||
session.doWork( connection -> {
|
||||
try (PreparedStatement statement = connection.prepareStatement(
|
||||
"insert \n" +
|
||||
" into\n" +
|
||||
" TEST_ENTITY\n" +
|
||||
" (firstLobField, secondLobField, clobfield, id) \n" +
|
||||
" values\n" +
|
||||
" (?, ?, ?, -1)"
|
||||
)) {
|
||||
int index = 1;
|
||||
statement.setString( index++, value1 );
|
||||
statement.setString( index++, value2 );
|
||||
statement.setString( index++, value3 );
|
||||
|
||||
assertEquals( 1, statement.executeUpdate() );
|
||||
}
|
||||
} )
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBadClobDataSavedAsStringFails(SessionFactoryScope scope) {
|
||||
try {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
final Query query = session.createQuery( "from TestEntity" );
|
||||
|
||||
final List<TestEntity> results = query.list();
|
||||
|
||||
fail( "Exception thrown expected" );
|
||||
} );
|
||||
}
|
||||
catch (Exception e) {
|
||||
Exception rootException = (Exception) ExceptionUtil.rootCause( e );
|
||||
assertTrue( rootException.getMessage().startsWith( "Bad value for type long" ) );
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBadClobDataSavedAsStringworksAfterUpdate(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
|
||||
session.doWork( connection -> {
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
statement.executeUpdate(
|
||||
"update test_entity\n" +
|
||||
"set \n" +
|
||||
" clobfield = lo_from_bytea(0, cast(clobfield as bytea)),\n" +
|
||||
" firstlobfield = lo_from_bytea(0, cast(firstlobfield as bytea)),\n" +
|
||||
" secondlobfield = lo_from_bytea(0, cast(secondlobfield as bytea))"
|
||||
);
|
||||
}
|
||||
} );
|
||||
} );
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
final Query query = session.createQuery( "from TestEntity" );
|
||||
|
||||
final List<TestEntity> 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( value3 ) );
|
||||
}
|
||||
catch (SQLException e) {
|
||||
fail( e.getMessage() );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void cleanUp(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session ->
|
||||
session.createQuery( "delete from TestEntity" ).executeUpdate()
|
||||
);
|
||||
}
|
||||
|
||||
@Entity(name = "TestEntity")
|
||||
@Table(name = "TEST_ENTITY")
|
||||
public static class TestEntity {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private long id;
|
||||
|
||||
@Lob
|
||||
@Column
|
||||
String firstLobField;
|
||||
|
||||
@Lob
|
||||
@Column
|
||||
String secondLobField;
|
||||
|
||||
@Lob
|
||||
@Column
|
||||
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;
|
||||
// }
|
||||
|
||||
// protected boolean isCleanupTestDataUsingBulkDelete() {
|
||||
// return true;
|
||||
// }
|
||||
}
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
// $Id: SerializableData.java 4704 2004-11-04 21:59:22Z steveebersole $
|
||||
package org.hibernate.test.lob;
|
||||
package org.hibernate.orm.test.lob;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
//$Id: $
|
||||
|
||||
package org.hibernate.test.lob;
|
||||
package org.hibernate.orm.test.lob;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
|
@ -9,7 +9,7 @@
|
|||
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
|
||||
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
|
||||
|
||||
<hibernate-mapping package="org.hibernate.test.lob">
|
||||
<hibernate-mapping package="org.hibernate.orm.test.lob">
|
||||
|
||||
<!-- HHH-7734: Don't use LOB_ENTITY as the table name. Others use it
|
||||
and there were some odd locking issue with 1 version of Oracle. -->
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* 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.orm.test.lob;
|
||||
|
||||
import org.hibernate.dialect.SybaseASEDialect;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.SkipForDialect;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
||||
|
||||
/**
|
||||
* Tests of {@link org.hibernate.type.SerializableType}
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@DomainModel(
|
||||
xmlMappings = "org/hibernate/orm/test/lob/SerializableMappings.hbm.xml"
|
||||
)
|
||||
@SessionFactory
|
||||
public class SerializableTypeTest {
|
||||
|
||||
@Test
|
||||
@SkipForDialect(dialectClass = SybaseASEDialect.class, version = 1500, matchSubTypes = true, reason = "HHH-6425")
|
||||
public void testNewSerializableType(SessionFactoryScope scope) {
|
||||
final String initialPayloadText = "Initial payload";
|
||||
final String changedPayloadText = "Changed payload";
|
||||
final String empty = "";
|
||||
|
||||
SerializableHolder serializableHolder = scope.fromTransaction(
|
||||
session -> {
|
||||
SerializableHolder holder = new SerializableHolder();
|
||||
session.save( holder );
|
||||
return holder;
|
||||
}
|
||||
);
|
||||
|
||||
Long id = serializableHolder.getId();
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
SerializableHolder holder = session.get( SerializableHolder.class, id );
|
||||
assertNull( holder.getSerialData() );
|
||||
holder.setSerialData( new SerializableData( initialPayloadText ) );
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
SerializableHolder holder = session.get( SerializableHolder.class, id );
|
||||
SerializableData serialData = (SerializableData) holder.getSerialData();
|
||||
assertEquals( initialPayloadText, serialData.getPayload() );
|
||||
holder.setSerialData( new SerializableData( changedPayloadText ) );
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
SerializableHolder holder = session.get( SerializableHolder.class, id );
|
||||
SerializableData serialData = (SerializableData) holder.getSerialData();
|
||||
assertEquals( changedPayloadText, serialData.getPayload() );
|
||||
holder.setSerialData( null );
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
SerializableHolder holder = session.get( SerializableHolder.class, id );
|
||||
assertNull( holder.getSerialData() );
|
||||
holder.setSerialData( new SerializableData( empty ) );
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
SerializableHolder holder = session.get( SerializableHolder.class, id );
|
||||
SerializableData serialData = (SerializableData) holder.getSerialData();
|
||||
assertEquals( empty, serialData.getPayload() );
|
||||
session.delete( holder );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -9,7 +9,7 @@
|
|||
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
|
||||
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
|
||||
|
||||
<hibernate-mapping package="org.hibernate.test.lob">
|
||||
<hibernate-mapping package="org.hibernate.orm.test.lob">
|
||||
|
||||
<class name="LongStringHolder" table="LOB_ENTITY_TEXT">
|
||||
<id name="id" type="long" column="ID">
|
|
@ -4,7 +4,9 @@
|
|||
* 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.lob;
|
||||
package org.hibernate.orm.test.lob;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
|
||||
/**
|
||||
* Test eager materialization and mutation data mapped by
|
||||
|
@ -12,8 +14,8 @@ package org.hibernate.test.lob;
|
|||
*
|
||||
* @author Gail Badner
|
||||
*/
|
||||
@DomainModel(
|
||||
xmlMappings = "org/hibernate/orm/test/lob/TextMappings.hbm.xml"
|
||||
)
|
||||
public class TextTest extends LongStringTest {
|
||||
public String[] getMappings() {
|
||||
return new String[] { "lob/TextMappings.hbm.xml" };
|
||||
}
|
||||
}
|
|
@ -1,99 +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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.lob;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.sql.Blob;
|
||||
import java.util.Random;
|
||||
|
||||
import org.hibernate.LobHelper;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.cfg.Configuration;
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.dialect.H2Dialect;
|
||||
import org.hibernate.testing.RequiresDialect;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author Brett Meyer
|
||||
*/
|
||||
@TestForIssue( jiraKey = "HHH-7698" )
|
||||
@RequiresDialect( value = H2Dialect.class, jiraKey = "HHH-7724" )
|
||||
public class JpaLargeBlobTest extends BaseCoreFunctionalTestCase {
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] { LobEntity.class };
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(Configuration configuration) {
|
||||
super.configure( configuration );
|
||||
configuration.setProperty(Environment.USE_STREAMS_FOR_BINARY, "true");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jpaBlobStream() throws Exception {
|
||||
Session session = openSession();
|
||||
LobEntity o = new LobEntity();
|
||||
|
||||
LobHelper lh = session.getLobHelper();
|
||||
LobInputStream lis = new LobInputStream();
|
||||
|
||||
session.getTransaction().begin();
|
||||
|
||||
Blob blob = lh.createBlob(lis, LobEntity.BLOB_LENGTH);
|
||||
o.setBlob(blob);
|
||||
|
||||
// Regardless if NON_CONTEXTUAL_LOB_CREATION is set to true,
|
||||
// ContextualLobCreator should use a NonContextualLobCreator to create
|
||||
// a blob Proxy. If that's the case, the InputStream will not be read
|
||||
// until it's persisted with the JDBC driver.
|
||||
// Although HHH-7698 was about high memory consumption, this is the best
|
||||
// way to test that the high memory use is being prevented.
|
||||
assertFalse( lis.wasRead() );
|
||||
|
||||
session.persist(o);
|
||||
session.getTransaction().commit();
|
||||
|
||||
assertTrue( lis.wasRead() );
|
||||
|
||||
session.close();
|
||||
|
||||
lis.close();
|
||||
}
|
||||
|
||||
private class LobInputStream extends InputStream {
|
||||
private boolean read = false;
|
||||
private Long count = (long) 200 * 1024 * 1024;
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
read = true;
|
||||
if (count > 0) {
|
||||
count--;
|
||||
return new Random().nextInt();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public boolean wasRead() {
|
||||
return read;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,237 +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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.lob;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.sql.Clob;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Lob;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import org.hibernate.dialect.CockroachDialect;
|
||||
import org.hibernate.dialect.PostgreSQLDialect;
|
||||
import org.hibernate.query.Query;
|
||||
import org.hibernate.testing.RequiresDialect;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
@TestForIssue(jiraKey = "HHH-11477")
|
||||
@RequiresDialect({ PostgreSQLDialect.class, CockroachDialect.class })
|
||||
public class LobStringTest extends BaseCoreFunctionalTestCase {
|
||||
|
||||
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();
|
||||
doInHibernate( this::sessionFactory, session -> {
|
||||
|
||||
entity.setFirstLobField( value1 );
|
||||
entity.setSecondLobField( value2 );
|
||||
entity.setClobField( session.getLobHelper().createClob( value2 ) );
|
||||
session.save( entity );
|
||||
} );
|
||||
|
||||
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() {
|
||||
doInHibernate( this::sessionFactory, session -> {
|
||||
final Query query = session.createQuery( "from TestEntity" );
|
||||
|
||||
final List<TestEntity> 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")
|
||||
@RequiresDialect(PostgreSQLDialect.class)
|
||||
public void testUsingStringLobAnnotatedPropertyInNativeQuery() {
|
||||
doInHibernate( this::sessionFactory, session -> {
|
||||
final List<TestEntity> results = session.createNativeQuery(
|
||||
"select te.* " +
|
||||
"from test_entity te " +
|
||||
"where lower(convert_from(lo_get(cast(te.firstLobField as oid)), 'UTF8')) LIKE :value", TestEntity.class )
|
||||
.setParameter( "value", value1 )
|
||||
.getResultList();
|
||||
|
||||
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")
|
||||
@RequiresDialect(PostgreSQLDialect.class)
|
||||
public void testSelectStringLobAnnotatedInNativeQuery() {
|
||||
doInHibernate( this::sessionFactory, session -> {
|
||||
final List<String> results = session.createNativeQuery(
|
||||
"select convert_from(lo_get(cast(te.secondLobField as oid)), 'UTF8') " +
|
||||
"from test_entity te " +
|
||||
"where lower(convert_from(lo_get(cast(te.firstLobField as oid)), 'UTF8')) LIKE :value" )
|
||||
.setParameter( "value", value1 )
|
||||
.list();
|
||||
|
||||
assertThat( results.size(), is( 1 ) );
|
||||
|
||||
assertThat( results.get( 0 ), is( value2 ) );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-11477")
|
||||
@RequiresDialect(PostgreSQLDialect.class)
|
||||
public void testUsingLobPropertyInNativeQuery() {
|
||||
doInHibernate( this::sessionFactory, session -> {
|
||||
final List<String> results = session.createNativeQuery(
|
||||
"select convert_from(lo_get(cast(te.secondLobField as oid)), 'UTF8') " +
|
||||
"from test_entity te " +
|
||||
"where lower(convert_from(lo_get(cast(te.clobField as oid)), 'UTF8')) LIKE :value" )
|
||||
.setParameter( "value", value2 )
|
||||
.list();
|
||||
|
||||
assertThat( results.size(), is( 1 ) );
|
||||
|
||||
assertThat( results.get( 0 ), is( value2 ) );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-11477")
|
||||
@RequiresDialect(PostgreSQLDialect.class)
|
||||
public void testSelectClobPropertyInNativeQuery() {
|
||||
doInHibernate( this::sessionFactory, session -> {
|
||||
final List<byte[]> results = session.createNativeQuery(
|
||||
"select lo_get(cast(te.clobField as oid)) " +
|
||||
"from test_entity te " +
|
||||
"where lower(convert_from(lo_get(cast(te.clobField as oid)), 'UTF8')) LIKE :value" )
|
||||
.setParameter( "value", value2 )
|
||||
.list();
|
||||
|
||||
assertThat( results.size(), is( 1 ) );
|
||||
|
||||
try {
|
||||
assertThat( new String( results.get( 0 ), "UTF8"), is( value2 ) );
|
||||
}
|
||||
catch (UnsupportedEncodingException 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();
|
||||
}
|
||||
}
|
|
@ -1,128 +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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.lob;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.hibernate.Session;
|
||||
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import junit.framework.AssertionFailedError;
|
||||
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
/**
|
||||
* Tests eager materialization and mutation of long byte arrays.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class LongByteArrayTest extends BaseCoreFunctionalTestCase {
|
||||
private static final int ARRAY_SIZE = 10000;
|
||||
|
||||
@Test
|
||||
public void testBoundedLongByteArrayAccess() {
|
||||
byte[] original = buildRecursively( ARRAY_SIZE, true );
|
||||
byte[] changed = buildRecursively( ARRAY_SIZE, false );
|
||||
byte[] empty = new byte[] {};
|
||||
|
||||
Session s = openSession();
|
||||
s.beginTransaction();
|
||||
LongByteArrayHolder entity = new LongByteArrayHolder();
|
||||
s.save( entity );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
entity = s.get( LongByteArrayHolder.class, entity.getId() );
|
||||
assertNull( entity.getLongByteArray() );
|
||||
entity.setLongByteArray( original );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
entity = s.get( LongByteArrayHolder.class, entity.getId() );
|
||||
Assert.assertEquals( ARRAY_SIZE, entity.getLongByteArray().length );
|
||||
assertEquals( original, entity.getLongByteArray() );
|
||||
entity.setLongByteArray( changed );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
entity = s.get( LongByteArrayHolder.class, entity.getId() );
|
||||
Assert.assertEquals( ARRAY_SIZE, entity.getLongByteArray().length );
|
||||
assertEquals( changed, entity.getLongByteArray() );
|
||||
entity.setLongByteArray( null );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
entity = s.get( LongByteArrayHolder.class, entity.getId() );
|
||||
assertNull( entity.getLongByteArray() );
|
||||
entity.setLongByteArray( empty );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
entity = s.get( LongByteArrayHolder.class, entity.getId() );
|
||||
if ( entity.getLongByteArray() != null ) {
|
||||
Assert.assertEquals( empty.length, entity.getLongByteArray().length );
|
||||
assertEquals( empty, entity.getLongByteArray() );
|
||||
}
|
||||
s.delete( entity );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSaving() {
|
||||
byte[] value = buildRecursively( ARRAY_SIZE, true );
|
||||
|
||||
Session s = openSession();
|
||||
s.beginTransaction();
|
||||
LongByteArrayHolder entity = new LongByteArrayHolder();
|
||||
entity.setLongByteArray( value );
|
||||
s.persist( entity );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
entity = ( LongByteArrayHolder ) s.get( LongByteArrayHolder.class, entity.getId() );
|
||||
Assert.assertEquals( ARRAY_SIZE, entity.getLongByteArray().length );
|
||||
assertEquals( value, entity.getLongByteArray() );
|
||||
s.delete( entity );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
private byte[] buildRecursively(int size, boolean on) {
|
||||
byte[] data = new byte[size];
|
||||
data[0] = mask( on );
|
||||
for ( int i = 0; i < size; i++ ) {
|
||||
data[i] = mask( on );
|
||||
on = !on;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
private byte mask(boolean on) {
|
||||
return on ? ( byte ) 1 : ( byte ) 0;
|
||||
}
|
||||
|
||||
public static void assertEquals(byte[] val1, byte[] val2) {
|
||||
if ( !Arrays.equals( val1, val2 ) ) {
|
||||
throw new AssertionFailedError( "byte arrays did not match" );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,99 +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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.lob;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.dialect.SybaseASE15Dialect;
|
||||
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
/**
|
||||
* Tests eager materialization and mutation of long strings.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@SuppressWarnings( {"UnusedDeclaration"})
|
||||
public abstract class LongStringTest extends BaseCoreFunctionalTestCase {
|
||||
private static final int LONG_STRING_SIZE = 10000;
|
||||
|
||||
@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();
|
||||
s.save( entity );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
entity = ( LongStringHolder ) s.get( LongStringHolder.class, entity.getId() );
|
||||
assertNull( entity.getLongString() );
|
||||
entity.setLongString( original );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
entity = ( LongStringHolder ) s.get( LongStringHolder.class, entity.getId() );
|
||||
assertEquals( LONG_STRING_SIZE, entity.getLongString().length() );
|
||||
assertEquals( original, entity.getLongString() );
|
||||
entity.setLongString( changed );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
entity = ( LongStringHolder ) s.get( LongStringHolder.class, entity.getId() );
|
||||
assertEquals( LONG_STRING_SIZE, entity.getLongString().length() );
|
||||
assertEquals( changed, entity.getLongString() );
|
||||
entity.setLongString( null );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
entity = ( LongStringHolder ) s.get( LongStringHolder.class, entity.getId() );
|
||||
assertNull( entity.getLongString() );
|
||||
entity.setLongString( empty );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
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() );
|
||||
}else{
|
||||
assertEquals( empty.length(), entity.getLongString().length() );
|
||||
assertEquals( empty, entity.getLongString() );
|
||||
}
|
||||
}
|
||||
s.delete( entity );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
private String buildRecursively(int size, char baseChar) {
|
||||
StringBuilder buff = new StringBuilder();
|
||||
for( int i = 0; i < size; i++ ) {
|
||||
buff.append( baseChar );
|
||||
}
|
||||
return buff.toString();
|
||||
}
|
||||
}
|
|
@ -1,189 +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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.lob;
|
||||
|
||||
import java.sql.Clob;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.List;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Lob;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import org.hibernate.dialect.PostgreSQLDialect;
|
||||
import org.hibernate.query.Query;
|
||||
|
||||
import org.hibernate.testing.*;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.hibernate.testing.util.ExceptionUtil;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
@TestForIssue(jiraKey = "HHH-11614")
|
||||
@RequiresDialect(PostgreSQLDialect.class)
|
||||
public class PostgreSqlLobStringTest extends BaseCoreFunctionalTestCase {
|
||||
|
||||
private final String value1 = "abc";
|
||||
private final String value2 = "def";
|
||||
private final String value3 = "ghi";
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class[] {TestEntity.class};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void prepareTest()
|
||||
throws Exception {
|
||||
|
||||
doInHibernate( this::sessionFactory, session -> {
|
||||
|
||||
session.doWork( connection -> {
|
||||
try(PreparedStatement statement = connection.prepareStatement(
|
||||
"insert \n" +
|
||||
" into\n" +
|
||||
" TEST_ENTITY\n" +
|
||||
" (firstLobField, secondLobField, clobfield, id) \n" +
|
||||
" values\n" +
|
||||
" (?, ?, ?, -1)"
|
||||
)) {
|
||||
int index = 1;
|
||||
statement.setString(index++, value1);
|
||||
statement.setString(index++, value2);
|
||||
statement.setString(index++, value3);
|
||||
|
||||
assertEquals( 1, statement.executeUpdate() );
|
||||
}
|
||||
} );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBadClobDataSavedAsStringFails() {
|
||||
try {
|
||||
doInHibernate( this::sessionFactory, session -> {
|
||||
final Query query = session.createQuery( "from TestEntity" );
|
||||
|
||||
final List<TestEntity> results = query.list();
|
||||
|
||||
fail("Exception thrown expected");
|
||||
} );
|
||||
}
|
||||
catch (Exception e) {
|
||||
Exception rootException = (Exception) ExceptionUtil.rootCause( e );
|
||||
assertTrue( rootException.getMessage().startsWith( "Bad value for type long" ) );
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBadClobDataSavedAsStringworksAfterUpdate() {
|
||||
doInHibernate( this::sessionFactory, session -> {
|
||||
|
||||
session.doWork( connection -> {
|
||||
try(Statement statement = connection.createStatement()) {
|
||||
statement.executeUpdate(
|
||||
"update test_entity\n" +
|
||||
"set \n" +
|
||||
" clobfield = lo_from_bytea(0, cast(clobfield as bytea)),\n" +
|
||||
" firstlobfield = lo_from_bytea(0, cast(firstlobfield as bytea)),\n" +
|
||||
" secondlobfield = lo_from_bytea(0, cast(secondlobfield as bytea))"
|
||||
);
|
||||
}
|
||||
} );
|
||||
} );
|
||||
|
||||
doInHibernate( this::sessionFactory, session -> {
|
||||
final Query query = session.createQuery( "from TestEntity" );
|
||||
|
||||
final List<TestEntity> 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( value3 ) );
|
||||
}
|
||||
catch (SQLException e) {
|
||||
fail( e.getMessage() );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
@Entity(name = "TestEntity")
|
||||
@Table(name = "TEST_ENTITY")
|
||||
public static class TestEntity {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private long id;
|
||||
|
||||
@Lob
|
||||
@Column
|
||||
String firstLobField;
|
||||
|
||||
@Lob
|
||||
@Column
|
||||
String secondLobField;
|
||||
|
||||
@Lob
|
||||
@Column
|
||||
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;
|
||||
}
|
||||
|
||||
protected boolean isCleanupTestDataUsingBulkDelete() {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,91 +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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.lob;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.dialect.SybaseASE15Dialect;
|
||||
import org.hibernate.testing.SkipForDialect;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
/**
|
||||
* Tests of {@link org.hibernate.type.SerializableType}
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class SerializableTypeTest extends BaseCoreFunctionalTestCase {
|
||||
public String[] getMappings() {
|
||||
return new String[] { "lob/SerializableMappings.hbm.xml" };
|
||||
}
|
||||
|
||||
public String getCacheConcurrencyStrategy() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Test
|
||||
@SkipForDialect( value = SybaseASE15Dialect.class, jiraKey = "HHH-6425")
|
||||
public void testNewSerializableType() {
|
||||
final String initialPayloadText = "Initial payload";
|
||||
final String changedPayloadText = "Changed payload";
|
||||
final String empty = "";
|
||||
|
||||
Session s = openSession();
|
||||
s.beginTransaction();
|
||||
SerializableHolder holder = new SerializableHolder();
|
||||
s.save( holder );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
holder = ( SerializableHolder ) s.get( SerializableHolder.class, holder.getId() );
|
||||
assertNull( holder.getSerialData() );
|
||||
holder.setSerialData( new SerializableData( initialPayloadText ) );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
holder = ( SerializableHolder ) s.get( SerializableHolder.class, holder.getId() );
|
||||
SerializableData serialData = ( SerializableData ) holder.getSerialData();
|
||||
assertEquals( initialPayloadText, serialData.getPayload() );
|
||||
holder.setSerialData( new SerializableData( changedPayloadText ) );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
holder = ( SerializableHolder ) s.get( SerializableHolder.class, holder.getId() );
|
||||
serialData = ( SerializableData ) holder.getSerialData();
|
||||
assertEquals( changedPayloadText, serialData.getPayload() );
|
||||
holder.setSerialData( null );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
holder = ( SerializableHolder ) s.get( SerializableHolder.class, holder.getId() );
|
||||
assertNull( holder.getSerialData() );
|
||||
holder.setSerialData( new SerializableData( empty ) );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
holder = ( SerializableHolder ) s.get( SerializableHolder.class, holder.getId() );
|
||||
serialData = ( SerializableData ) holder.getSerialData();
|
||||
assertEquals( empty, serialData.getPayload() );
|
||||
s.delete( holder );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
}
|
|
@ -368,4 +368,10 @@ abstract public class DialectFeatureChecks {
|
|||
return dialect.currentTimestamp().startsWith( "current_timestamp" );
|
||||
}
|
||||
}
|
||||
|
||||
public static class ForceLobAsLastValue implements DialectFeatureCheck {
|
||||
public boolean apply(Dialect dialect) {
|
||||
return dialect.forceLobAsLastValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue