Skip to content

Commit bee200a

Browse files
committed
HHH-12835 Fix an incorrect assertion in BatchFetchQueueHelper
1 parent d85831f commit bee200a

File tree

4 files changed

+204
-1
lines changed

4 files changed

+204
-1
lines changed

hibernate-core/src/main/java/org/hibernate/engine/internal/BatchFetchQueueHelper.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,12 @@ public static void removeNotFoundBatchLoadableEntityKeys(
5454
}
5555
LOG.debug( "Not all entities were loaded." );
5656
Set<Serializable> idSet = new HashSet<>( Arrays.asList( ids ) );
57+
int originalIdSetSize = idSet.size();
5758
for ( Object result : results ) {
5859
// All results should be in the PersistenceContext
5960
idSet.remove( session.getContextEntityIdentifier( result ) );
6061
}
61-
assert idSet.size() == ids.length - results.size();
62+
assert idSet.size() == originalIdSetSize - results.size();
6263
if ( LOG.isDebugEnabled() ) {
6364
LOG.debug( "Entities of type [" + persister.getEntityName() + "] not found; IDs: " + idSet );
6465
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
5+
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
6+
*/
7+
package org.hibernate.test.batchfetch;
8+
9+
import javax.persistence.Column;
10+
import javax.persistence.Entity;
11+
import javax.persistence.FetchType;
12+
import javax.persistence.GeneratedValue;
13+
import javax.persistence.GenerationType;
14+
import javax.persistence.Id;
15+
import javax.persistence.JoinColumn;
16+
import javax.persistence.ManyToOne;
17+
import javax.persistence.Table;
18+
19+
@Entity
20+
@Table(name = "city")
21+
public class City {
22+
23+
@Id
24+
@GeneratedValue(strategy = GenerationType.AUTO)
25+
@Column(name = "id")
26+
private Integer id;
27+
28+
@Column(name = "name")
29+
private String name;
30+
31+
@ManyToOne(fetch = FetchType.LAZY)
32+
@JoinColumn(name = "country_id")
33+
private Country country;
34+
35+
public City() {
36+
}
37+
38+
public City(String name, Country country) {
39+
super();
40+
this.name = name;
41+
this.country = country;
42+
}
43+
44+
public Integer getId() {
45+
return id;
46+
}
47+
48+
public void setId(Integer id) {
49+
this.id = id;
50+
}
51+
52+
public String getName() {
53+
return name;
54+
}
55+
56+
public void setName(String name) {
57+
this.name = name;
58+
}
59+
60+
public Country getCountry() {
61+
return country;
62+
}
63+
64+
public void setCountry(Country country) {
65+
this.country = country;
66+
}
67+
68+
@Override
69+
public String toString() {
70+
return name + " (" + ( country == null ? "?" : country.getName() ) + ")";
71+
}
72+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
5+
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
6+
*/
7+
package org.hibernate.test.batchfetch;
8+
9+
import java.util.List;
10+
11+
import javax.persistence.Column;
12+
import javax.persistence.Entity;
13+
import javax.persistence.GeneratedValue;
14+
import javax.persistence.GenerationType;
15+
import javax.persistence.Id;
16+
import javax.persistence.OneToMany;
17+
import javax.persistence.Table;
18+
19+
@Entity
20+
@Table(name = "country")
21+
public class Country {
22+
23+
@Id
24+
@GeneratedValue(strategy = GenerationType.AUTO)
25+
@Column(name = "id")
26+
private Integer id;
27+
28+
@Column(name = "name")
29+
private String name;
30+
31+
@OneToMany(mappedBy = "country")
32+
private List<City> cities;
33+
34+
public Country() {
35+
}
36+
37+
public Country(String name) {
38+
super();
39+
this.name = name;
40+
}
41+
42+
public Integer getId() {
43+
return id;
44+
}
45+
46+
public void setId(Integer id) {
47+
this.id = id;
48+
}
49+
50+
public String getName() {
51+
return name;
52+
}
53+
54+
public void setName(String name) {
55+
this.name = name;
56+
}
57+
58+
public List<City> getCities() {
59+
return cities;
60+
}
61+
62+
@Override
63+
public String toString() {
64+
return name;
65+
}
66+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
5+
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
6+
*/
7+
package org.hibernate.test.batchfetch;
8+
9+
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
10+
import static org.junit.Assert.assertNotNull;
11+
12+
import java.util.List;
13+
import java.util.stream.IntStream;
14+
15+
import org.hibernate.cfg.AvailableSettings;
16+
import org.hibernate.cfg.Configuration;
17+
import org.hibernate.loader.BatchFetchStyle;
18+
import org.hibernate.testing.TestForIssue;
19+
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
20+
import org.junit.Test;
21+
22+
public class PaddedBatchFetchTestCase extends BaseCoreFunctionalTestCase {
23+
24+
@Override
25+
protected Class<?>[] getAnnotatedClasses() {
26+
return new Class<?>[]{ Country.class, City.class };
27+
}
28+
29+
@Override
30+
protected void configure(Configuration configuration) {
31+
super.configure( configuration );
32+
33+
configuration.setProperty( AvailableSettings.SHOW_SQL, Boolean.TRUE.toString() );
34+
configuration.setProperty( AvailableSettings.FORMAT_SQL, Boolean.TRUE.toString() );
35+
36+
configuration.setProperty( AvailableSettings.BATCH_FETCH_STYLE, BatchFetchStyle.PADDED.name() );
37+
configuration.setProperty( AvailableSettings.DEFAULT_BATCH_FETCH_SIZE, "15" );
38+
}
39+
40+
@Test
41+
@TestForIssue(jiraKey = "HHH-12835")
42+
public void paddedBatchFetchTest() throws Exception {
43+
doInHibernate( this::sessionFactory, session -> {
44+
// Having DEFAULT_BATCH_FETCH_SIZE=15
45+
// results in batchSizes = [15, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
46+
// Let's create 11 countries so batch size 15 will be used with padded values,
47+
// this causes to have to remove 4 elements from list
48+
int numberOfCountries = 11;
49+
50+
IntStream.range( 0, numberOfCountries ).forEach( i -> {
51+
Country c = new Country( "Country " + i );
52+
session.save( c );
53+
session.save( new City( "City " + i, c ) );
54+
} );
55+
} );
56+
57+
doInHibernate( this::sessionFactory, session -> {
58+
List<City> allCities = session.createQuery( "from City", City.class ).list();
59+
60+
// this triggers countries to be fetched in batch
61+
assertNotNull( allCities.get( 0 ).getCountry().getName() );
62+
} );
63+
}
64+
}

0 commit comments

Comments
 (0)