HHH-18773 Deduplicate result initializers to avoid double initialization issues

This commit is contained in:
Christian Beikov 2024-10-26 16:04:19 +02:00
parent a63716dab7
commit e024bd0568
2 changed files with 60 additions and 2 deletions

View File

@ -4,7 +4,7 @@
*/ */
package org.hibernate.sql.results.jdbc.internal; package org.hibernate.sql.results.jdbc.internal;
import java.util.ArrayList; import java.util.LinkedHashSet;
import org.hibernate.sql.results.graph.DomainResultAssembler; import org.hibernate.sql.results.graph.DomainResultAssembler;
import org.hibernate.sql.results.graph.Initializer; import org.hibernate.sql.results.graph.Initializer;
@ -37,7 +37,7 @@ public class JdbcValuesMappingResolutionImpl implements JdbcValuesMappingResolut
} }
private static Initializer<?>[] getResultInitializers(DomainResultAssembler<?>[] resultAssemblers) { private static Initializer<?>[] getResultInitializers(DomainResultAssembler<?>[] resultAssemblers) {
final ArrayList<Initializer<?>> initializers = new ArrayList<>( resultAssemblers.length ); final LinkedHashSet<Initializer<?>> initializers = new LinkedHashSet<>( resultAssemblers.length );
for ( DomainResultAssembler<?> resultAssembler : resultAssemblers ) { for ( DomainResultAssembler<?> resultAssembler : resultAssemblers ) {
resultAssembler.forEachResultAssembler( (initializer, list) -> list.add( initializer ), initializers ); resultAssembler.forEachResultAssembler( (initializer, list) -> list.add( initializer ), initializers );
} }

View File

@ -0,0 +1,58 @@
/*
* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.orm.test.query;
import org.hibernate.testing.orm.junit.DomainModel;
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.Entity;
import jakarta.persistence.Id;
@DomainModel(annotatedClasses = {
SelectJoinedAssociationMultipleTimesTest.Book.class
})
@SessionFactory
public class SelectJoinedAssociationMultipleTimesTest {
@Test
public void test(SessionFactoryScope scope) {
scope.inTransaction(
session -> {
// Add a proxy first to trigger the error
session.getReference( Book.class, 1 );
session.createSelectionQuery( "select b b1, b b2 from Book b", Object[].class ).getResultList();
}
);
}
@BeforeEach
public void prepareTestData(SessionFactoryScope scope) {
scope.inTransaction( (session) -> session.persist( new Book( 1, "First book" ) ) );
}
@AfterEach
public void dropTestData(SessionFactoryScope scope) {
scope.inTransaction( (session) -> session.createMutationQuery( "delete Book" ).executeUpdate() );
}
@Entity( name = "Book")
public static class Book {
@Id
private Integer id;
private String name;
public Book() {
}
public Book(Integer id, String name) {
this.id = id;
this.name = name;
}
}
}