Skip to content

Commit e7acf02

Browse files
committed
[#2108] Add test for StatelessSession insertAll in batch does not do batching
1 parent aa2c177 commit e7acf02

File tree

2 files changed

+172
-0
lines changed

2 files changed

+172
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
/* Hibernate, Relational Persistence for Idiomatic Java
2+
*
3+
* SPDX-License-Identifier: Apache-2.0
4+
* Copyright: Red Hat Inc. and Hibernate Authors
5+
*/
6+
package org.hibernate;
7+
8+
import java.util.Objects;
9+
import java.util.Set;
10+
11+
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
12+
import org.hibernate.cfg.Configuration;
13+
import org.hibernate.reactive.BaseReactiveTest;
14+
import org.hibernate.reactive.testing.SqlStatementTracker;
15+
16+
import org.junit.jupiter.api.BeforeEach;
17+
import org.junit.jupiter.api.Test;
18+
19+
import io.vertx.junit5.Timeout;
20+
import io.vertx.junit5.VertxTestContext;
21+
import jakarta.persistence.Entity;
22+
import jakarta.persistence.Id;
23+
import jakarta.persistence.Table;
24+
import jakarta.persistence.Version;
25+
26+
import static java.util.concurrent.TimeUnit.MINUTES;
27+
import static org.assertj.core.api.Assertions.assertThat;
28+
29+
@Timeout(value = 10, timeUnit = MINUTES)
30+
public class PersistAllWithNoBatchSizeConfiguredTest extends BaseReactiveTest {
31+
private static SqlStatementTracker sqlTracker;
32+
33+
@Override
34+
protected Set<Class<?>> annotatedEntities() {
35+
return Set.of( GuineaPig.class );
36+
}
37+
38+
@Override
39+
protected Configuration constructConfiguration() {
40+
Configuration configuration = super.constructConfiguration();
41+
42+
// Construct a tracker that collects query statements via the SqlStatementLogger framework.
43+
// Pass in configuration properties to hand off any actual logging properties
44+
sqlTracker = new SqlStatementTracker(
45+
PersistAllWithNoBatchSizeConfiguredTest::filter,
46+
configuration.getProperties()
47+
);
48+
return configuration;
49+
}
50+
51+
@BeforeEach
52+
public void clearTracker() {
53+
sqlTracker.clear();
54+
}
55+
56+
protected void addServices(StandardServiceRegistryBuilder builder) {
57+
sqlTracker.registerService( builder );
58+
}
59+
60+
private static boolean filter(String s) {
61+
String[] accepted = { "insert ", "update ", "delete " };
62+
for ( String valid : accepted ) {
63+
if ( s.toLowerCase().startsWith( valid ) ) {
64+
return true;
65+
}
66+
}
67+
return false;
68+
}
69+
70+
@Test
71+
public void testBatchingWithStateless(VertxTestContext context) {
72+
final GuineaPig[] pigs = {
73+
new GuineaPig( 11, "One" ),
74+
new GuineaPig( 22, "Two" ),
75+
new GuineaPig( 33, "Three" ),
76+
new GuineaPig( 44, "Four" ),
77+
new GuineaPig( 55, "Five" ),
78+
new GuineaPig( 66, "Six" ),
79+
};
80+
test( context, getMutinySessionFactory()
81+
.withStatelessTransaction( s -> s.insertAll( 10, pigs ) )
82+
.invoke( () -> {
83+
// We expect only one insert query
84+
assertThat( sqlTracker.getLoggedQueries() ).hasSize( 1 );
85+
// Parameters are different for different dbs, so we cannot do an exact match
86+
assertThat( sqlTracker.getLoggedQueries().get( 0 ) )
87+
.matches("insert into pig \\(name,version,id\\) values (.*)" );
88+
sqlTracker.clear();
89+
} )
90+
);
91+
}
92+
93+
@Entity(name = "GuineaPig")
94+
@Table(name = "pig")
95+
public static class GuineaPig {
96+
@Id
97+
private Integer id;
98+
private String name;
99+
@Version
100+
private int version;
101+
102+
public GuineaPig() {
103+
}
104+
105+
public GuineaPig(Integer id, String name) {
106+
this.id = id;
107+
this.name = name;
108+
}
109+
110+
public Integer getId() {
111+
return id;
112+
}
113+
114+
public void setId(Integer id) {
115+
this.id = id;
116+
}
117+
118+
public String getName() {
119+
return name;
120+
}
121+
122+
public void setName(String name) {
123+
this.name = name;
124+
}
125+
126+
@Override
127+
public String toString() {
128+
return id + ": " + name;
129+
}
130+
131+
@Override
132+
public boolean equals(Object o) {
133+
if ( this == o ) {
134+
return true;
135+
}
136+
if ( o == null || getClass() != o.getClass() ) {
137+
return false;
138+
}
139+
GuineaPig guineaPig = (GuineaPig) o;
140+
return Objects.equals( name, guineaPig.name );
141+
}
142+
143+
@Override
144+
public int hashCode() {
145+
return Objects.hash( name );
146+
}
147+
}
148+
149+
}

hibernate-reactive-core/src/test/java/org/hibernate/reactive/BatchingConnectionTest.java

+23
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,29 @@ public void testBatchingWithStateless(VertxTestContext context) {
168168
);
169169
}
170170

171+
@Test
172+
public void testInsertAllWithStateless(VertxTestContext context) {
173+
final GuineaPig[] pigs = {
174+
new GuineaPig( 11, "One" ),
175+
new GuineaPig( 22, "Two" ),
176+
new GuineaPig( 33, "Three" ),
177+
new GuineaPig( 44, "Four" ),
178+
new GuineaPig( 55, "Five" ),
179+
new GuineaPig( 66, "Six" ),
180+
};
181+
test( context, getMutinySessionFactory()
182+
.withStatelessTransaction( s -> s.insertAll( pigs ) )
183+
.invoke( () -> {
184+
// We only 2 insert queries, batch size is 5 and we have 6 inserts
185+
assertThat( sqlTracker.getLoggedQueries() ).hasSize( 2 );
186+
// Parameters are different for different dbs, so we cannot do an exact match
187+
assertThat( sqlTracker.getLoggedQueries().get( 0 ) )
188+
.matches("insert into pig \\(name,version,id\\) values (.*)" );
189+
sqlTracker.clear();
190+
} )
191+
);
192+
}
193+
171194
@Test
172195
public void testBatchingConnection(VertxTestContext context) {
173196
test( context, openSession()

0 commit comments

Comments
 (0)