-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add systematic tests for before native query flushing in JPA and plai…
…n Hibernate
- Loading branch information
Showing
2 changed files
with
235 additions
and
0 deletions.
There are no files selected for viewing
125 changes: 125 additions & 0 deletions
125
...rnate-core/src/test/java/org/hibernate/orm/test/jpa/autoflush/HibernateAutoflushTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
/* | ||
* SPDX-License-Identifier: LGPL-2.1-or-later | ||
* Copyright Red Hat Inc. and Hibernate Authors | ||
*/ | ||
package org.hibernate.orm.test.jpa.autoflush; | ||
|
||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.FlushModeType; | ||
import jakarta.persistence.Id; | ||
import org.hibernate.query.QueryFlushMode; | ||
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.Test; | ||
|
||
import java.util.List; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
|
||
@SessionFactory | ||
@DomainModel(annotatedClasses = HibernateAutoflushTest.Thing.class) | ||
public class HibernateAutoflushTest { | ||
|
||
@Test void test1(SessionFactoryScope scope) { | ||
scope.getSessionFactory().getSchemaManager().truncate(); | ||
scope.inTransaction( em -> { | ||
em.persist( new Thing( "Widget" ) ); | ||
List<Thing> resultList = | ||
em.createNativeQuery( "select * from thing", Thing.class ) | ||
.getResultList(); | ||
// Hibernate does NOT autoflush before a native query | ||
assertEquals( 0, resultList.size() ); | ||
} ); | ||
} | ||
|
||
@Test void test2(SessionFactoryScope scope) { | ||
scope.getSessionFactory().getSchemaManager().truncate(); | ||
scope.inTransaction( em -> { | ||
em.persist( new Thing("Widget") ); | ||
List<String> resultList = | ||
em.createNativeQuery( "select typeofthing from thing", String.class ) | ||
.getResultList(); | ||
// Hibernate does NOT autoflush before a native query | ||
assertEquals(0, resultList.size()); | ||
} ); | ||
} | ||
|
||
@Test void test3(SessionFactoryScope scope) { | ||
scope.getSessionFactory().getSchemaManager().truncate(); | ||
scope.inSession( em -> { | ||
em.persist( new Thing("Widget") ); | ||
List<Thing> resultList = | ||
em.createNativeQuery( "select * from thing", Thing.class ) | ||
.getResultList(); | ||
// spec says we must NOT flush before native query outside tx | ||
assertEquals(0, resultList.size()); | ||
} ); | ||
} | ||
|
||
@Test void test4(SessionFactoryScope scope) { | ||
scope.getSessionFactory().getSchemaManager().truncate(); | ||
scope.inTransaction( em -> { | ||
em.setFlushMode( FlushModeType.COMMIT ); | ||
em.persist( new Thing("Widget") ); | ||
List<Thing> resultList = | ||
em.createNativeQuery( "select * from thing", Thing.class ) | ||
.getResultList(); | ||
// spec says we must NOT flush before native query with FMT.COMMIT | ||
assertEquals(0, resultList.size()); | ||
} ); | ||
} | ||
|
||
@Test void test5(SessionFactoryScope scope) { | ||
scope.getSessionFactory().getSchemaManager().truncate(); | ||
scope.inTransaction( em -> { | ||
em.persist( new Thing("Widget") ); | ||
List<Thing> resultList = | ||
em.createNativeQuery( "select * from thing", Thing.class ) | ||
.addSynchronizedQuerySpace( "Thing" ) | ||
.getResultList(); | ||
// we should not flush because user specified that the query touches the table | ||
assertEquals(1, resultList.size()); | ||
} ); | ||
} | ||
|
||
@Test void test6(SessionFactoryScope scope) { | ||
scope.getSessionFactory().getSchemaManager().truncate(); | ||
scope.inTransaction( em -> { | ||
em.persist( new Thing("Widget") ); | ||
List<Thing> resultList = | ||
em.createNativeQuery( "select * from thing", Thing.class ) | ||
.addSynchronizedQuerySpace( "XXX" ) | ||
.getResultList(); | ||
// we should not flush because user specified that the query doesn't touch the table | ||
assertEquals(0, resultList.size()); | ||
} ); | ||
} | ||
|
||
@Test void test7(SessionFactoryScope scope) { | ||
scope.getSessionFactory().getSchemaManager().truncate(); | ||
scope.inTransaction( em -> { | ||
em.persist( new Thing( "Widget" ) ); | ||
List<Thing> resultList = | ||
em.createNativeQuery( "select * from thing", Thing.class ) | ||
.setQueryFlushMode( QueryFlushMode.FLUSH ) | ||
.getResultList(); | ||
// we should flush because of the QueryFlushMode | ||
assertEquals( 1, resultList.size() ); | ||
} ); | ||
} | ||
|
||
@Entity(name="Thing") | ||
public static class Thing { | ||
@Id | ||
long id; | ||
String typeOfThing; | ||
|
||
public Thing(String typeOfThing) { | ||
this.typeOfThing = typeOfThing; | ||
} | ||
|
||
public Thing() { | ||
} | ||
} | ||
} |
110 changes: 110 additions & 0 deletions
110
hibernate-core/src/test/java/org/hibernate/orm/test/jpa/autoflush/JpaAutoflushTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
/* | ||
* SPDX-License-Identifier: LGPL-2.1-or-later | ||
* Copyright Red Hat Inc. and Hibernate Authors | ||
*/ | ||
package org.hibernate.orm.test.jpa.autoflush; | ||
|
||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.FlushModeType; | ||
import jakarta.persistence.Id; | ||
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope; | ||
import org.hibernate.testing.orm.junit.Jpa; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import java.util.List; | ||
|
||
import static org.hibernate.jpa.HibernateHints.HINT_NATIVE_SPACES; | ||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
|
||
@Jpa(annotatedClasses = JpaAutoflushTest.Thing.class) | ||
public class JpaAutoflushTest { | ||
|
||
@Test void test1(EntityManagerFactoryScope scope) { | ||
scope.getEntityManagerFactory().getSchemaManager().truncate(); | ||
scope.inTransaction( em -> { | ||
em.persist( new Thing( "Widget" ) ); | ||
List<?> resultList = | ||
em.createNativeQuery( "select * from thing", Thing.class ) | ||
.getResultList(); | ||
// spec says we must flush before native query in tx | ||
assertEquals( 1, resultList.size() ); | ||
} ); | ||
} | ||
|
||
@Test void test2(EntityManagerFactoryScope scope) { | ||
scope.getEntityManagerFactory().getSchemaManager().truncate(); | ||
scope.inTransaction( em -> { | ||
em.persist( new Thing("Widget") ); | ||
List<?> resultList = | ||
em.createNativeQuery( "select typeofthing from thing", String.class ) | ||
.getResultList(); | ||
// spec says we must flush before native query in tx | ||
assertEquals(1, resultList.size()); | ||
} ); | ||
} | ||
|
||
@Test void test3(EntityManagerFactoryScope scope) { | ||
scope.getEntityManagerFactory().getSchemaManager().truncate(); | ||
scope.inEntityManager( em -> { | ||
em.persist( new Thing("Widget") ); | ||
List<?> resultList = | ||
em.createNativeQuery( "select * from thing", Thing.class ) | ||
.getResultList(); | ||
// spec says we must NOT flush before native query outside tx | ||
assertEquals(0, resultList.size()); | ||
} ); | ||
} | ||
|
||
@Test void test4(EntityManagerFactoryScope scope) { | ||
scope.getEntityManagerFactory().getSchemaManager().truncate(); | ||
scope.inTransaction( em -> { | ||
em.setFlushMode( FlushModeType.COMMIT ); | ||
em.persist( new Thing("Widget") ); | ||
List<?> resultList = | ||
em.createNativeQuery( "select * from thing", Thing.class ) | ||
.getResultList(); | ||
// spec says we must NOT flush before native query with FMT.COMMIT | ||
assertEquals(0, resultList.size()); | ||
} ); | ||
} | ||
|
||
@Test void test5(EntityManagerFactoryScope scope) { | ||
scope.getEntityManagerFactory().getSchemaManager().truncate(); | ||
scope.inTransaction( em -> { | ||
em.persist( new Thing("Widget") ); | ||
List<?> resultList = | ||
em.createNativeQuery( "select * from thing", Thing.class ) | ||
.setHint( HINT_NATIVE_SPACES, "Thing" ) | ||
.getResultList(); | ||
// we should not flush because user specified that the query touches the table | ||
assertEquals(1, resultList.size()); | ||
} ); | ||
} | ||
|
||
@Test void test6(EntityManagerFactoryScope scope) { | ||
scope.getEntityManagerFactory().getSchemaManager().truncate(); | ||
scope.inTransaction( em -> { | ||
em.persist( new Thing("Widget") ); | ||
List<?> resultList = | ||
em.createNativeQuery( "select * from thing", Thing.class ) | ||
.setHint( HINT_NATIVE_SPACES, "XXX" ) | ||
.getResultList(); | ||
// we should not flush because user specified that the query doesn't touch the table | ||
assertEquals(0, resultList.size()); | ||
} ); | ||
} | ||
|
||
@Entity(name="Thing") | ||
public static class Thing { | ||
@Id | ||
long id; | ||
String type; | ||
|
||
public Thing(String type) { | ||
this.type = type; | ||
} | ||
|
||
public Thing() { | ||
} | ||
} | ||
} |