HHH-12555 Fix merging of lazy loaded blobs/clobs/nclobs
It's better to avoid pushing UNFETCHED_PROPERTY to the types as it requires all the types to take it into account. TypeHelper looks like the only sensible caller that needs change.
This commit is contained in:
parent
c79ce44f84
commit
1af878166f
|
@ -71,11 +71,7 @@ public abstract class AbstractStandardBasicType<T>
|
|||
}
|
||||
|
||||
protected T getReplacement(T original, T target, SharedSessionContractImplementor session) {
|
||||
if ( original == LazyPropertyInitializer.UNFETCHED_PROPERTY ) {
|
||||
return target;
|
||||
}
|
||||
else if ( !isMutable() ||
|
||||
( target != LazyPropertyInitializer.UNFETCHED_PROPERTY && isEqual( original, target ) ) ) {
|
||||
if ( !isMutable() || ( target != null && isEqual( original, target ) ) ) {
|
||||
return original;
|
||||
}
|
||||
else {
|
||||
|
@ -351,6 +347,10 @@ public abstract class AbstractStandardBasicType<T>
|
|||
@Override
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
public final Object replace(Object original, Object target, SharedSessionContractImplementor session, Object owner, Map copyCache) {
|
||||
if ( original == null && target == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return getReplacement( (T) original, (T) target, session );
|
||||
}
|
||||
|
||||
|
|
|
@ -7,8 +7,12 @@
|
|||
package org.hibernate.type;
|
||||
|
||||
import java.sql.Blob;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.engine.jdbc.LobCreator;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.internal.util.collections.ArrayHelper;
|
||||
import org.hibernate.type.descriptor.java.BlobTypeDescriptor;
|
||||
|
||||
/**
|
||||
|
@ -36,7 +40,23 @@ public class BlobType extends AbstractSingleColumnStandardBasicType<Blob> {
|
|||
|
||||
@Override
|
||||
protected Blob getReplacement(Blob original, Blob target, SharedSessionContractImplementor session) {
|
||||
if ( target == null ) {
|
||||
return copyOriginalBlob( (Blob) original, session );
|
||||
}
|
||||
|
||||
return session.getJdbcServices().getJdbcEnvironment().getDialect().getLobMergeStrategy().mergeBlob( original, target, session );
|
||||
}
|
||||
|
||||
private Blob copyOriginalBlob(Blob original, SharedSessionContractImplementor session) {
|
||||
try {
|
||||
final LobCreator lobCreator = session.getFactory().getServiceRegistry().getService( JdbcServices.class ).getLobCreator(
|
||||
session );
|
||||
return original == null
|
||||
? lobCreator.createBlob( ArrayHelper.EMPTY_BYTE_ARRAY )
|
||||
: lobCreator.createBlob( original.getBinaryStream(), original.length() );
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw session.getJdbcServices().getSqlExceptionHelper().convert( e, "unable to merge BLOB data" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,10 @@
|
|||
package org.hibernate.type;
|
||||
|
||||
import java.sql.Clob;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.engine.jdbc.LobCreator;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.type.descriptor.java.ClobTypeDescriptor;
|
||||
|
||||
|
@ -36,7 +39,21 @@ public class ClobType extends AbstractSingleColumnStandardBasicType<Clob> {
|
|||
|
||||
@Override
|
||||
protected Clob getReplacement(Clob original, Clob target, SharedSessionContractImplementor session) {
|
||||
return session.getJdbcServices().getJdbcEnvironment().getDialect().getLobMergeStrategy().mergeClob( original, target, session );
|
||||
if ( target == null ) {
|
||||
return copyOriginalClob( (Clob) original, session );
|
||||
}
|
||||
return session.getJdbcServices().getJdbcEnvironment().getDialect().getLobMergeStrategy().mergeClob( (Clob) original, (Clob) target, session );
|
||||
}
|
||||
|
||||
private Clob copyOriginalClob(Clob original, SharedSessionContractImplementor session) {
|
||||
try {
|
||||
final LobCreator lobCreator = session.getFactory().getServiceRegistry().getService( JdbcServices.class ).getLobCreator( session );
|
||||
return original == null
|
||||
? lobCreator.createClob( "" )
|
||||
: lobCreator.createClob( original.getCharacterStream(), original.length() );
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw session.getJdbcServices().getSqlExceptionHelper().convert( e, "unable to merge CLOB data" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,12 +7,15 @@
|
|||
package org.hibernate.type;
|
||||
|
||||
import java.sql.NClob;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.engine.jdbc.LobCreator;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.type.descriptor.java.NClobTypeDescriptor;
|
||||
|
||||
/**
|
||||
* A type that maps between {@link java.sql.Types#CLOB CLOB} and {@link java.sql.Clob}
|
||||
* A type that maps between {@link java.sql.Types#NCLOB NCLOB} and {@link java.sql.NClob}
|
||||
*
|
||||
* @author Gavin King
|
||||
* @author Steve Ebersole
|
||||
|
@ -36,7 +39,21 @@ public class NClobType extends AbstractSingleColumnStandardBasicType<NClob> {
|
|||
|
||||
@Override
|
||||
protected NClob getReplacement(NClob original, NClob target, SharedSessionContractImplementor session) {
|
||||
if ( target == null ) {
|
||||
return copyOriginalNClob( original, session );
|
||||
}
|
||||
return session.getJdbcServices().getJdbcEnvironment().getDialect().getLobMergeStrategy().mergeNClob( original, target, session );
|
||||
}
|
||||
|
||||
private NClob copyOriginalNClob(NClob original, SharedSessionContractImplementor session) {
|
||||
try {
|
||||
final LobCreator lobCreator = session.getFactory().getServiceRegistry().getService( JdbcServices.class ).getLobCreator( session );
|
||||
return original == null
|
||||
? lobCreator.createNClob( "" )
|
||||
: lobCreator.createNClob( original.getCharacterStream(), original.length() );
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw session.getJdbcServices().getSqlExceptionHelper().convert( e, "unable to merge NCLOB data" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -159,6 +159,9 @@ public class TypeHelper {
|
|||
if ( original[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY || original[i] == PropertyAccessStrategyBackRefImpl.UNKNOWN ) {
|
||||
copied[i] = target[i];
|
||||
}
|
||||
else if ( target[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY ) {
|
||||
copied[i] = types[i].replace( original[i], null, session, owner, copyCache );
|
||||
}
|
||||
else {
|
||||
copied[i] = types[i].replace( original[i], target[i], session, owner, copyCache );
|
||||
}
|
||||
|
@ -193,6 +196,9 @@ public class TypeHelper {
|
|||
|| original[i] == PropertyAccessStrategyBackRefImpl.UNKNOWN ) {
|
||||
copied[i] = target[i];
|
||||
}
|
||||
else if ( target[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY ) {
|
||||
copied[i] = types[i].replace( original[i], null, session, owner, copyCache, foreignKeyDirection );
|
||||
}
|
||||
else {
|
||||
copied[i] = types[i].replace( original[i], target[i], session, owner, copyCache, foreignKeyDirection );
|
||||
}
|
||||
|
|
|
@ -6,6 +6,23 @@
|
|||
*/
|
||||
package org.hibernate.test.type;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.sql.Time;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Calendar;
|
||||
import java.util.Currency;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.Locale;
|
||||
import java.util.SimpleTimeZone;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.hibernate.bytecode.enhance.spi.LazyPropertyInitializer;
|
||||
import org.hibernate.internal.SessionImpl;
|
||||
import org.hibernate.internal.util.SerializationHelper;
|
||||
|
@ -42,26 +59,11 @@ import org.hibernate.type.TimeType;
|
|||
import org.hibernate.type.TimeZoneType;
|
||||
import org.hibernate.type.TimestampType;
|
||||
import org.hibernate.type.TrueFalseType;
|
||||
import org.hibernate.type.Type;
|
||||
import org.hibernate.type.TypeHelper;
|
||||
import org.hibernate.type.YesNoType;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.sql.Time;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Calendar;
|
||||
import java.util.Currency;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.Locale;
|
||||
import java.util.SimpleTimeZone;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
|
@ -344,8 +346,11 @@ public class TypeTest extends BaseUnitTestCase {
|
|||
assertTrue( original == type.replace( original, copy, null, null, null ) );
|
||||
|
||||
// following tests assert that types work with properties not yet loaded in bytecode enhanced entities
|
||||
assertSame( copy, type.replace( LazyPropertyInitializer.UNFETCHED_PROPERTY, copy, null, null, null ) );
|
||||
assertNotEquals( LazyPropertyInitializer.UNFETCHED_PROPERTY, type.replace( original, LazyPropertyInitializer.UNFETCHED_PROPERTY, null, null, null ) );
|
||||
Type[] types = new Type[]{ type };
|
||||
assertSame( copy, TypeHelper.replace( new Object[]{ LazyPropertyInitializer.UNFETCHED_PROPERTY },
|
||||
new Object[]{ copy }, types, null, null, null )[0] );
|
||||
assertNotEquals( LazyPropertyInitializer.UNFETCHED_PROPERTY, TypeHelper.replace( new Object[]{ original },
|
||||
new Object[]{ LazyPropertyInitializer.UNFETCHED_PROPERTY }, types, null, null, null )[0] );
|
||||
|
||||
assertTrue( type.isSame( original, copy ) );
|
||||
assertTrue( type.isEqual( original, copy ) );
|
||||
|
|
Loading…
Reference in New Issue