Skip to content

Commit a678b57

Browse files
authored
fix(GH-273): detach result entities from entity manager persistent context (#275)
* fix(GH-273): add detach entity in result list stream * fix: detach result entity for singular queries * fix: add unit test * fix: update testGH273 * fix: polish test
1 parent 978d9d0 commit a678b57

File tree

3 files changed

+99
-3
lines changed

3 files changed

+99
-3
lines changed

graphql-jpa-query-example-simple/src/main/resources/application.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ spring:
55
open-in-view: false
66
h2:
77
console.enabled: true
8+
datasource:
9+
url: jdbc:h2:mem:starwars
810

911
graphql:
1012
jpa:

graphql-jpa-query-schema/src/main/java/com/introproventures/graphql/jpa/query/schema/impl/GraphQLJpaQueryFactory.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,8 @@ protected <T> Stream<T> getResultStream(TypedQuery<T> query,
262262

263263
// Let's execute query and get wrap result into stream
264264
return query.getResultList()
265-
.stream();
265+
.stream()
266+
.peek(entityManager::detach);
266267
}
267268

268269
protected Object querySingleResult(final DataFetchingEnvironment environment) {
@@ -285,7 +286,13 @@ protected Object querySingleResult(final DataFetchingEnvironment environment) {
285286
logger.info("\nGraphQL JPQL Single Result Query String:\n {}", getJPQLQueryString(query));
286287
}
287288

288-
return query.getSingleResult();
289+
Object result = query.getSingleResult();
290+
291+
if (result != null) {
292+
entityManager.detach(result);
293+
}
294+
295+
return result;
289296
}
290297

291298
return null;

graphql-jpa-query-schema/src/test/java/com/introproventures/graphql/jpa/query/schema/StarwarsQueryExecutorTests.java

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,17 @@
3232
import org.springframework.boot.autoconfigure.SpringBootApplication;
3333
import org.springframework.boot.test.context.SpringBootTest;
3434
import org.springframework.context.annotation.Bean;
35+
import org.springframework.transaction.PlatformTransactionManager;
36+
import org.springframework.transaction.support.TransactionTemplate;
3537

3638
import com.introproventures.graphql.jpa.query.AbstractSpringBootTestSupport;
3739
import com.introproventures.graphql.jpa.query.schema.impl.GraphQLJpaExecutor;
3840
import com.introproventures.graphql.jpa.query.schema.impl.GraphQLJpaSchemaBuilder;
3941
import com.introproventures.graphql.jpa.query.schema.model.starwars.Character;
4042
import com.introproventures.graphql.jpa.query.schema.model.starwars.Droid;
43+
import com.introproventures.graphql.jpa.query.schema.model.starwars.Human;
4144

4245
@SpringBootTest
43-
@Transactional
4446
public class StarwarsQueryExecutorTests extends AbstractSpringBootTestSupport {
4547

4648
@SpringBootApplication
@@ -66,6 +68,9 @@ public GraphQLSchemaBuilder graphQLSchemaBuilder(final EntityManager entityManag
6668

6769
@Autowired
6870
private EntityManager em;
71+
72+
@Autowired
73+
private PlatformTransactionManager txManager;
6974

7075
@Test
7176
public void contextLoads() {
@@ -2118,4 +2123,86 @@ public void queryWithInLineExplicitOptionalFalseForSingularAttributeAndWhereSear
21182123
assertThat(result.toString()).isEqualTo(expected);
21192124
}
21202125

2126+
// https://github.com/introproventures/graphql-jpa-query/issues/273
2127+
@Test
2128+
public void testGH273Plural() {
2129+
2130+
//given:
2131+
String query = "{" +
2132+
" Humans(where: {id: {EQ: \"1000\"}}) {" +
2133+
" select {" +
2134+
" id" +
2135+
" name" +
2136+
" }" +
2137+
" }" +
2138+
"}";
2139+
2140+
// given
2141+
new TransactionTemplate(txManager).executeWithoutResult((txStatus) -> {
2142+
Object result = executor.execute(query).getData();
2143+
2144+
String expected = "{Humans={select=[{id=1000, name=Luke Skywalker}]}}";
2145+
2146+
assertThat(result.toString()).isEqualTo(expected);
2147+
2148+
Human human = em.find(Human.class, "1000");
2149+
2150+
human.setName("Luky Skywalker");
2151+
});
2152+
2153+
// when
2154+
new TransactionTemplate(txManager).executeWithoutResult((txStatus) -> {
2155+
// then
2156+
Object result = executor.execute(query).getData();
2157+
2158+
String updated = "{Humans={select=[{id=1000, name=Luky Skywalker}]}}";;
2159+
2160+
assertThat(result.toString()).isEqualTo(updated);
2161+
2162+
Human human = em.find(Human.class, "1000");
2163+
2164+
human.setName("Luke Skywalker");
2165+
});
2166+
}
2167+
2168+
// https://github.com/introproventures/graphql-jpa-query/issues/273
2169+
@Test
2170+
public void testGH273Singular() {
2171+
2172+
//given:
2173+
String query = "{" +
2174+
" Human(id: \"1000\" ) {" +
2175+
" id" +
2176+
" name" +
2177+
" }" +
2178+
" " +
2179+
"}";
2180+
2181+
// given
2182+
new TransactionTemplate(txManager).executeWithoutResult((txStatus) -> {
2183+
Object result = executor.execute(query).getData();
2184+
2185+
String expected = "{Human={id=1000, name=Luke Skywalker}}";
2186+
2187+
assertThat(result.toString()).isEqualTo(expected);
2188+
2189+
Human human = em.find(Human.class, "1000");
2190+
2191+
human.setName("Luky Skywalker");
2192+
});
2193+
2194+
// when
2195+
new TransactionTemplate(txManager).executeWithoutResult((txStatus) -> {
2196+
// then
2197+
Object result = executor.execute(query).getData();
2198+
2199+
String updated = "{Human={id=1000, name=Luky Skywalker}}";
2200+
2201+
assertThat(result.toString()).isEqualTo(updated);
2202+
2203+
Human human = em.find(Human.class, "1000");
2204+
2205+
human.setName("Luke Skywalker");
2206+
});
2207+
}
21212208
}

0 commit comments

Comments
 (0)