Skip to content

Commit e0feff4

Browse files
committed
HHH-16991 Fix array based id restriction with EnhanceUserType
1 parent 350a139 commit e0feff4

File tree

3 files changed

+326
-34
lines changed

3 files changed

+326
-34
lines changed

hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionBatchLoaderArrayParam.java

Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -102,20 +102,22 @@ public CollectionBatchLoaderArrayParam(
102102
.buildSelectTranslator( getSessionFactory(), sqlSelect )
103103
.translate( JdbcParameterBindings.NO_BINDINGS, QueryOptions.NONE );
104104
}
105+
105106
@Override
106107
public PersistentCollection<?> load(Object keyBeingLoaded, SharedSessionContractImplementor session) {
107108
final var keyDescriptor = getLoadable().getKeyDescriptor();
108-
if ( keyDescriptor.isEmbedded() ) {
109+
if ( keyDescriptor.isEmbedded()
110+
|| keyDescriptor.getKeyPart().getSingleJdbcMapping().getValueConverter() != null ) {
109111
assert keyDescriptor.getJdbcTypeCount() == 1;
110-
return loadEmbeddable( keyBeingLoaded, session, keyDescriptor );
112+
return loadWithConversion( keyBeingLoaded, session, keyDescriptor );
111113
}
112114
else {
113115
return super.load( keyBeingLoaded, session );
114116
}
115117
}
116118

117119
@AllowReflection
118-
private PersistentCollection<?> loadEmbeddable(
120+
private PersistentCollection<?> loadWithConversion(
119121
Object keyBeingLoaded,
120122
SharedSessionContractImplementor session,
121123
ForeignKeyDescriptor keyDescriptor) {
@@ -126,7 +128,7 @@ private PersistentCollection<?> loadEmbeddable(
126128

127129
final int length = getDomainBatchSize();
128130
final Object[] keysToInitialize = new Object[length];
129-
final Object[] embeddedKeys = new Object[length];
131+
final Object[] domainKeys = new Object[length];
130132
session.getPersistenceContextInternal().getBatchFetchQueue()
131133
.collectBatchLoadableCollectionKeys(
132134
length,
@@ -135,7 +137,7 @@ private PersistentCollection<?> loadEmbeddable(
135137
key,
136138
(i, value, jdbcMapping) -> {
137139
keysToInitialize[index] = value;
138-
embeddedKeys[index] = key;
140+
domainKeys[index] = key;
139141
},
140142
session
141143
)
@@ -152,7 +154,7 @@ private PersistentCollection<?> loadEmbeddable(
152154

153155
initializeKeys( keyBeingLoaded, keys, session );
154156

155-
for ( Object initializedKey : embeddedKeys ) {
157+
for ( Object initializedKey : domainKeys ) {
156158
if ( initializedKey != null ) {
157159
finishInitializingKey( initializedKey, session );
158160
}
@@ -175,7 +177,7 @@ void initializeKeys(Object key, Object[] keysToInitialize, SharedSessionContract
175177
assert jdbcSelectOperation != null;
176178
assert jdbcParameter != null;
177179

178-
final var jdbcParameterBindings = new JdbcParameterBindingsImpl(1);
180+
final var jdbcParameterBindings = new JdbcParameterBindingsImpl( 1 );
179181
jdbcParameterBindings.addBinding(
180182
jdbcParameter,
181183
new JdbcParameterBindingImpl( arraySqlTypedMapping.getJdbcMapping(), keysToInitialize )
@@ -206,31 +208,10 @@ void finishInitializingKeys(Object[] keys, SharedSessionContractImplementor sess
206208
}
207209

208210
@Override
209-
@AllowReflection
210211
Object[] resolveKeysToInitialize(Object keyBeingLoaded, SharedSessionContractImplementor session) {
211-
final var keyDescriptor = getLoadable().getKeyDescriptor();
212-
if( keyDescriptor.isEmbedded()){
213-
assert keyDescriptor.getJdbcTypeCount() == 1;
214-
final int length = getDomainBatchSize();
215-
final var keysToInitialize = new Object[length];
216-
session.getPersistenceContextInternal().getBatchFetchQueue()
217-
.collectBatchLoadableCollectionKeys(
218-
length,
219-
(index, key) ->
220-
keyDescriptor.forEachJdbcValue(
221-
key,
222-
(i, value, jdbcMapping) -> {
223-
keysToInitialize[index] = value;
224-
},
225-
session
226-
)
227-
,
228-
keyBeingLoaded,
229-
getLoadable()
230-
);
231-
// now trim down the array to the number of keys we found
232-
return trimIdBatch( length, keysToInitialize );
233-
}
212+
assert !getLoadable().getKeyDescriptor().isEmbedded()
213+
&& getLoadable().getKeyDescriptor().getKeyPart().getSingleJdbcMapping().getValueConverter() == null
214+
: "Should use loadWithConversion() instead";
234215
return super.resolveKeysToInitialize( keyBeingLoaded, session );
235216
}
236217
}

hibernate-core/src/main/java/org/hibernate/sql/exec/internal/JdbcParameterBindingImpl.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77

88
import org.hibernate.metamodel.mapping.JdbcMapping;
99
import org.hibernate.sql.exec.spi.JdbcParameterBinding;
10+
import org.hibernate.type.descriptor.java.BasicPluralJavaType;
11+
12+
import java.util.Arrays;
13+
import java.util.Locale;
1014

1115
/**
1216
* @author Andrea Boriero
@@ -16,9 +20,12 @@ public class JdbcParameterBindingImpl implements JdbcParameterBinding {
1620
private final Object bindValue;
1721

1822
public JdbcParameterBindingImpl(JdbcMapping jdbcMapping, Object bindValue) {
19-
// assert bindValue == null || jdbcMapping == null || jdbcMapping.getJdbcJavaType().isInstance( bindValue )
20-
// : String.format( Locale.ROOT, "Unexpected value type (expected : %s) : %s (%s)",
21-
// jdbcMapping.getJdbcJavaType().getJavaTypeClass().getName(), bindValue, bindValue.getClass().getName() );
23+
assert bindValue == null || jdbcMapping == null || jdbcMapping.getJdbcJavaType().isInstance( bindValue )
24+
|| jdbcMapping.getJdbcJavaType() instanceof BasicPluralJavaType<?> pluralJavaType
25+
&& bindValue instanceof Object[] objects
26+
&& Arrays.stream( objects ).allMatch( pluralJavaType.getElementJavaType()::isInstance )
27+
: String.format( Locale.ROOT, "Unexpected value type (expected : %s) : %s (%s)",
28+
jdbcMapping.getJdbcJavaType().getJavaTypeClass().getName(), bindValue, bindValue.getClass().getName() );
2229

2330
this.jdbcMapping = jdbcMapping;
2431
this.bindValue = bindValue;

0 commit comments

Comments
 (0)