Skip to content

Commit 6e49895

Browse files
committed
[#2735] Test for Hibernate dirty detection fails in case entity member are initialized
1 parent 9482956 commit 6e49895

File tree

2 files changed

+114
-0
lines changed
  • integration-tests/bytecode-enhancements-it/src

2 files changed

+114
-0
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.reactive.it.dirtychecking;
6+
7+
import jakarta.persistence.Entity;
8+
import jakarta.persistence.Id;
9+
10+
@Entity
11+
public class Fruit {
12+
@Id
13+
private int id;
14+
15+
// Dirty checking should not be confused by this initialization.
16+
private String name = "Banana";
17+
18+
public int getId() {
19+
return id;
20+
}
21+
22+
public Fruit setId(final int id) {
23+
this.id = id;
24+
return this;
25+
}
26+
27+
public String getName() {
28+
return name;
29+
}
30+
31+
public Fruit setName(final String name) {
32+
this.name = name;
33+
return this;
34+
}
35+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.reactive.it;
6+
7+
import java.util.Collection;
8+
import java.util.List;
9+
import java.util.concurrent.CompletionStage;
10+
11+
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
12+
import org.hibernate.cfg.Configuration;
13+
import org.hibernate.reactive.it.dirtychecking.Fruit;
14+
15+
import org.hibernate.testing.SqlStatementTracker;
16+
import org.junit.jupiter.api.BeforeEach;
17+
import org.junit.jupiter.api.Test;
18+
19+
import io.vertx.junit5.VertxTestContext;
20+
21+
import static org.assertj.core.api.Assertions.assertThat;
22+
import static org.hibernate.reactive.util.impl.CompletionStages.voidFuture;
23+
24+
public class DirtyCheckingIT extends BaseReactiveIT {
25+
26+
private static SqlStatementTracker sqlTracker;
27+
28+
@Override
29+
protected Configuration constructConfiguration() {
30+
Configuration configuration = super.constructConfiguration();
31+
32+
// Construct a tracker that collects query statements via the SqlStatementLogger framework.
33+
// Pass in configuration properties to hand off any actual logging properties
34+
sqlTracker = new SqlStatementTracker( DirtyCheckingIT::updateQueryFilter, configuration.getProperties() );
35+
return configuration;
36+
}
37+
38+
private static boolean updateQueryFilter(String s) {
39+
return s.toLowerCase().startsWith( "update " );
40+
}
41+
42+
@BeforeEach
43+
public void clearTracker() {
44+
sqlTracker.clear();
45+
}
46+
47+
@Override
48+
protected void addServices(StandardServiceRegistryBuilder builder) {
49+
sqlTracker.registerService( builder );
50+
}
51+
52+
@Override
53+
protected Collection<Class<?>> annotatedEntities() {
54+
return List.of( Fruit.class );
55+
}
56+
57+
@Override
58+
protected CompletionStage<Void> cleanDb() {
59+
// There's only one test, so we don't need to clean the db.
60+
// This prevents extra queries in the log when the test is over.
61+
return voidFuture();
62+
}
63+
64+
@Test
65+
public void testDirtyCheck(VertxTestContext context) {
66+
test(
67+
context,
68+
getMutinySessionFactory()
69+
.withTransaction( s -> s.persist( new Fruit().setId( 5 ).setName( "Apple" ) ) )
70+
.chain( () -> getMutinySessionFactory().withTransaction( s -> s.find( Fruit.class, 5 ) ) )
71+
.invoke( fruit -> {
72+
assertThat( fruit ).hasFieldOrPropertyWithValue( "name", "Apple" );
73+
assertThat( sqlTracker.getLoggedQueries() )
74+
.as( "Dirty field detection failed, unexpected SQL mutation query" )
75+
.isEmpty();
76+
} )
77+
);
78+
}
79+
}

0 commit comments

Comments
 (0)