HHH-15479 Add Results#addUnique(R result)

This commit is contained in:
Andrea Boriero 2022-08-10 14:19:43 +02:00 committed by Christian Beikov
parent 1905b03c95
commit 12aaaff766

View File

@ -7,14 +7,13 @@
package org.hibernate.sql.results.spi; package org.hibernate.sql.results.spi;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Set;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.engine.spi.PersistenceContext; import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.IdentitySet;
import org.hibernate.query.ResultListTransformer; import org.hibernate.query.ResultListTransformer;
import org.hibernate.query.spi.QueryOptions; import org.hibernate.query.spi.QueryOptions;
import org.hibernate.sql.results.internal.RowProcessingStateStandardImpl; import org.hibernate.sql.results.internal.RowProcessingStateStandardImpl;
@ -115,7 +114,7 @@ public Results(JavaType resultJavaType) {
this.resultJavaType = resultJavaType; this.resultJavaType = resultJavaType;
} }
public boolean contains(R result) { private boolean contains(R result) {
for ( int i = 0; i < results.size(); i++ ) { for ( int i = 0; i < results.size(); i++ ) {
if ( resultJavaType.areEqual( results.get( i ), result ) ) { if ( resultJavaType.areEqual( results.get( i ), result ) ) {
return true; return true;
@ -124,6 +123,14 @@ public boolean contains(R result) {
return false; return false;
} }
public boolean addUnique(R result) {
if ( contains( result ) ) {
return false;
}
results.add( result );
return true;
}
public void add(R result) { public void add(R result) {
results.add( result ); results.add( result );
} }
@ -134,20 +141,22 @@ public List<R> getResults() {
} }
private static class EntityResult<R> extends Results<R> { private static class EntityResult<R> extends Results<R> {
private final Set<R> added = new IdentitySet<>(); private static final Object DUMP_VALUE = new Object();
private final IdentityHashMap<R, Object> added = new IdentityHashMap<>();
public EntityResult(JavaType resultJavaType) { public EntityResult(JavaType resultJavaType) {
super( resultJavaType ); super( resultJavaType );
} }
public boolean contains(R result) { public boolean addUnique(R result) {
return added.contains( result ); if ( added.put( result, DUMP_VALUE ) == null ) {
super.add( result );
return true;
}
return false;
} }
public void add(R result) {
super.add( result );
added.add( result );
}
} }
@Override @Override
@ -263,19 +272,14 @@ private static <R> void withDuplicationCheck(
Results<R> results, Results<R> results,
RowProcessingStateStandardImpl rowProcessingState, RowProcessingStateStandardImpl rowProcessingState,
boolean throwException) { boolean throwException) {
if ( results.contains( result ) ) { if ( !results.addUnique( result ) && throwException && !rowProcessingState.hasCollectionInitializers ) {
if ( throwException && !rowProcessingState.hasCollectionInitializers ) { throw new HibernateException(
throw new HibernateException( String.format(
String.format( Locale.ROOT,
Locale.ROOT, "Duplicate row was found and `%s` was specified",
"Duplicate row was found and `%s` was specified", UniqueSemantic.ASSERT
UniqueSemantic.ASSERT )
) );
);
}
}
else {
results.add( result );
} }
} }