👉 기본 환경

- Language: Java

- DB: H2 Database

- IDE: IntelliJ

 

 

테스트 코드가 안돌아갑니다.

Transaction이 closed 됐다고 안돌아갑니다😖.

 

 

⌨️ 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@SpringBootTest
public class PostServiceTest {
 
    @Autowired
    private PostService postService;
 
    @Autowired
    private PostRepository postRepository;
 
    @Test
    public void DTO데이터_POST테이블_조회(){
        // given
        PostSaveDTO dto = PostSaveDTO.builder()
                .title("서비스 타이틀")
                .content("서비스 컨텐츠")
                .author("서비스 작가")
                .build();
 
        // when
        Long saveId = postService.savePost(dto);
        List<Posts> postList = postRepository.findAllDesc().toList();
 
        // then
        // Dto 클래스가 service.save 메소드에 전달되면, DB에 잘 저장되었는지 검증
        Posts findPost = postList.get(1);
        assertThat(findPost.getTitle()).isEqualTo(dto.getTitle());
        assertThat(findPost.getAuthor()).isEqualTo(dto.getAuthor());
 
    }
}
 
 

 

 

🖨️오류

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl@5c4e86e7 is closed
java.lang.IllegalStateException: org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl@5c4e86e7 is closed
    at org.hibernate.resource.jdbc.internal.AbstractLogicalConnectionImplementor.errorIfClosed(AbstractLogicalConnectionImplementor.java:37)
    at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getPhysicalConnection(LogicalConnectionManagedImpl.java:142)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.connection(StatementPreparerImpl.java:51)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:150)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:177)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:152)
    at org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl.lambda$scroll$1(JdbcSelectExecutorStandardImpl.java:122)
    at org.hibernate.sql.results.jdbc.internal.DeferredResultSetAccess.executeQuery(DeferredResultSetAccess.java:226)
    at org.hibernate.sql.results.jdbc.internal.DeferredResultSetAccess.getResultSet(DeferredResultSetAccess.java:163)
    at org.hibernate.sql.results.jdbc.internal.JdbcValuesResultSetImpl.advanceNext(JdbcValuesResultSetImpl.java:254)
    at org.hibernate.sql.results.jdbc.internal.JdbcValuesResultSetImpl.processNext(JdbcValuesResultSetImpl.java:134)
    at org.hibernate.sql.results.jdbc.internal.AbstractJdbcValues.next(AbstractJdbcValues.java:19)
    at org.hibernate.sql.results.internal.RowProcessingStateStandardImpl.next(RowProcessingStateStandardImpl.java:66)
    at org.hibernate.internal.ScrollableResultsImpl.next(ScrollableResultsImpl.java:51)
    at org.hibernate.query.internal.ScrollableResultsIterator.hasNext(ScrollableResultsIterator.java:33)
    at java.base/java.util.Iterator.forEachRemaining(Iterator.java:132)
    at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1845)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:575)
    at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:260)
    at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:616)
    at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:622)
    at java.base/java.util.stream.ReferencePipeline.toList(ReferencePipeline.java:627)
    at com.project.mini1.webservice.PostServiceTest.DTO데이터_POST테이블_조회(PostServiceTest.java:58)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:727)
    at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
    at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86)
    at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103)
    at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
    at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92)
    at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:217)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:213)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:138)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
    at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:110)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:90)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:85)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
    at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
    at jdk.proxy1/jdk.proxy1.$Proxy2.stop(Unknown Source)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
    at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
    at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113)
    at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65)
    at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
    at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
 

 

 

📡 원인

테스트 실행 중에 이미 다른 곳에서 해당 연결(LogicalConnection)을 닫음

 

 

📰 해결 방법

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
@SpringBootTest
public class PostServiceTest {
 
    @Autowired
    private PostService postService;
 
    @Autowired
    private PostRepository postRepository;
 
    @Test
    public void DTO데이터_POST테이블_저장(){
        // given
        PostSaveDTO dto = PostSaveDTO.builder()
                .title("서비스 타이틀")
                .content("서비스 컨텐츠")
                .author("서비스 작가")
                .build();
 
        // when
        Long saveId = postService.savePost(dto);
        Posts findPost = postRepository.findOne(saveId);
 
        // then
        // Dto 클래스가 service.save 메소드에 전달되면, DB에 잘 저장되었는지 검증
        assertThat(findPost.getTitle()).isEqualTo(dto.getTitle());
        assertThat(findPost.getContent()).isEqualTo(dto.getContent());
        assertThat(findPost.getAuthor()).isEqualTo(dto.getAuthor());
 
    }
 
    @Test
    public void DTO데이터_POST테이블_조회(){
        // given
        PostSaveDTO dto = PostSaveDTO.builder()
                .title("서비스 타이틀")
                .content("서비스 컨텐츠")
                .author("서비스 작가")
                .build();
        Long saveId = postService.savePost(dto);
 
        // when
        List<PostsMainResponseDTO> postList = postService.findAllPostsDesc();
 
        // then
        // Dto 클래스가 service.save 메소드에 전달되면, DB에 잘 저장되었는지 검증
        PostsMainResponseDTO findPostDTO = postList.get(1);
        assertThat(findPostDTO.getTitle()).isEqualTo(dto.getTitle());
        assertThat(findPostDTO.getAuthor()).isEqualTo(dto.getAuthor());
 
    }
}
 
 

postRepository.findAllDesc().toList() → postService.findAllPostsDesc()

- postRepository.findAllDesc().toList()

    - toList()를 호출하여 스트림을 리스트로 변환하려고 하는데, 이 과정에서 실제 데이터베이스 연결(LogicalConnection)을 사용

    - 테스트 실행 중에 이미 postPost(dto)에서 해당 연결(LogicalConnection)을 닫음

        → org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl@5784f6b9 is closed 에러가 발생

- postService.findAllPostsDesc()

    - 트랜잭션 처리가 자동으로 이루어짐(findAllPostsDesc: @Transactional(readOnly=true) 선언 됨)

        = @Transactional이 선언되어 있으므로 새로운 트랜잭션을 열고 데이터베이스 연결을 유지

 

👉 기본 환경

- Language: Java

- DB: H2 Database

- IDE: IntelliJ

 

 

⌨️ 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public class Main {
    public static void main(String[] args) {
 
        // 생략
 
        try {
 
            Team team = new Team();
            team.setName("Team");
            em.persist(team);
 
            Member member = new Member();
            member.setName("Member");
            member.setAge(10);
            member.setTeam(team);
            member.setType(MemberType.ADMIN);
            em.persist(member);
 
            em.flush();
            em.clear();
 
            String query = "select t.members.name from Team t";
 
            List<String> members = em.createQuery(query, String.class)
                    .getResultList();
 
            tx.commit(); // transaction 종료 후 commit
        } catch (Exception e) {
            tx.rollback(); // 문제가 생길 경우, rollback 진행
            e.printStackTrace();
        } finally {
            em.close(); // tx에 문제가 생기더라도 em 반드시 종료
        }
 
 
        emf.close();
        // 트랜잭션 단위로 관리되는 Entity Manager는 Tx가 종료되면 close가 되어야하지만, emf는 Application 종료 시, close되어야 함
 
    }
}
 

 

 

🖨️오류

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
java.lang.IllegalArgumentException: org.hibernate.QueryException: illegal attempt to dereference collection [team0_.id.members] with element property reference [name] [select t.members.name from jpql.Team t]
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:138)
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181)
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:188)
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:725)
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:816)
    at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:23)
    at jpql.Main.main(Main.java:139)
Caused by: org.hibernate.QueryException: illegal attempt to dereference collection [team0_.id.members] with element property reference [name] [select t.members.name from jpql.Team t]
    at org.hibernate.QueryException.generateQueryException(QueryException.java:120)
    at org.hibernate.QueryException.wrapWithQueryString(QueryException.java:103)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:220)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:144)
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:113)
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:73)
    at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:155)
    at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:604)
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:716)
    ... 3 more
Caused by: org.hibernate.QueryException: illegal attempt to dereference collection [team0_.id.members] with element property reference [name]
    at org.hibernate.hql.internal.ast.tree.DotNode$1.buildIllegalCollectionDereferenceException(DotNode.java:59)
    at org.hibernate.hql.internal.ast.tree.DotNode.checkLhsIsNotCollection(DotNode.java:639)
    at org.hibernate.hql.internal.ast.tree.DotNode.resolve(DotNode.java:245)
    at org.hibernate.hql.internal.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:114)
    at org.hibernate.hql.internal.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:109)
    at org.hibernate.hql.internal.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:104)
    at org.hibernate.hql.internal.ast.tree.DotNode.resolveSelectExpression(DotNode.java:768)
    at org.hibernate.hql.internal.ast.HqlSqlWalker.resolveSelectExpression(HqlSqlWalker.java:1065)
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectExpr(HqlSqlBaseWalker.java:2319)
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectExprList(HqlSqlBaseWalker.java:2256)
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectClause(HqlSqlBaseWalker.java:1518)
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:597)
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:325)
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:273)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:272)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:192)
    ... 9 more
 
 

 

 

📡 원인

컬렉션 요소에 대한 직접적인 접근 시도

(Hibernate는 컬렉션에 대한 직접적인 접근을 허용하지 않음)

 

 

📰 해결 방법

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public class Main {
    public static void main(String[] args) {
 
        // 생략
 
        try {
 
            Team team = new Team();
            team.setName("Team");
            em.persist(team);
 
            Member member = new Member();
            member.setName("Member");
            member.setAge(10);
            member.setTeam(team);
            member.setType(MemberType.ADMIN);
            em.persist(member);
 
            em.flush();
            em.clear();
 
            String query = "select m.name from Team t join t.members m ";
 
            List<String> members = em.createQuery(query, String.class)
                    .getResultList();
 
            tx.commit(); // transaction 종료 후 commit
        } catch (Exception e) {
            tx.rollback(); // 문제가 생길 경우, rollback 진행
            e.printStackTrace();
        } finally {
            em.close(); // tx에 문제가 생기더라도 em 반드시 종료
        }
 
 
        emf.close();
        // 트랜잭션 단위로 관리되는 Entity Manager는 Tx가 종료되면 close가 되어야하지만, emf는 Application 종료 시, close되어야 함
 
    }
}
 

FROM 절에서 명시적 조인을 통해 별칭을 얻으면 별칭을 통해 탐색

 

👉 기본 환경

- Language: Java

- DB: H2 Database

- IDE: IntelliJ

 

 

⌨️ 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class Main {
    public static void main(String[] args) {
        
        // 생략
 
        try {
            Team team = new Team();
            team.setName("Team");
            em.persist(team);
 
            Member member = new Member();
            member.setName("Member");
            member.setAge(10);
            member.setTeam(team);
            em.persist(member);
 
            em.flush();
            em.clear();
 
            String query = "select m from Member m join m.team t on t.name :name";
 
            List<Member> members = em.createQuery(query, Member.class)
                    .setParameter("name""Team")
                    .getResultList();
 
            System.out.println("members.size: " + members.size());
            for (Member m : members)
                System.out.println("member: " + m);
 
            tx.commit(); // transaction 종료 후 commit
        } catch (Exception e) {
            tx.rollback(); // 문제가 생길 경우, rollback 진행
            e.printStackTrace();
        } finally {
            em.close(); // tx에 문제가 생기더라도 em 반드시 종료
        }
 
        emf.close();
 
    }
}
 
 

 

 

🖨️오류

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
line 1:54: unexpected token: name
    at org.hibernate.hql.internal.antlr.HqlBaseParser.queryRule(HqlBaseParser.java:767)
    at org.hibernate.hql.internal.antlr.HqlBaseParser.selectStatement(HqlBaseParser.java:319)
    at org.hibernate.hql.internal.antlr.HqlBaseParser.statement(HqlBaseParser.java:198)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:290)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:189)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:144)
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:113)
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:73)
    at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:155)
    at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:604)
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:716)
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:816)
    at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:23)
    at jpql.Main.main(Main.java:137)
 
java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: : near line 1, column 53 [select m from jpql.Member m join m.team t on t.name :name]
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:138)
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181)
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:188)
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:725)
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:816)
    at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:23)
    at jpql.Main.main(Main.java:137)
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: : near line 1, column 53 [select m from jpql.Member m join m.team t on t.name :name]
    at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:74)
    at org.hibernate.hql.internal.ast.ErrorTracker.throwQueryException(ErrorTracker.java:93)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:297)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:189)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:144)
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:113)
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:73)
    at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:155)
    at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:604)
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:716)
    ... 3 more
 
 

 

 

📡 원인

JPQL 구문 오류

ON 조건절이 올바르지 않음

 

 

📰 해결 방법

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class Main {
    public static void main(String[] args) {
        
        // 생략
 
        try {
            Team team = new Team();
            team.setName("Team");
            em.persist(team);
 
            Member member = new Member();
            member.setName("Member");
            member.setAge(10);
            member.setTeam(team);
            em.persist(member);
 
            em.flush();
            em.clear();
 
            String query = "select m from Member m join m.team t on t.name= :name";
 
            List<Member> members = em.createQuery(query, Member.class)
                    .setParameter("name""Team")
                    .getResultList();
 
            System.out.println("members.size: " + members.size());
            for (Member m : members)
                System.out.println("member: " + m);
 
            tx.commit(); // transaction 종료 후 commit
        } catch (Exception e) {
            tx.rollback(); // 문제가 생길 경우, rollback 진행
            e.printStackTrace();
        } finally {
            em.close(); // tx에 문제가 생기더라도 em 반드시 종료
        }
 
        emf.close();
 
    }
}
 
 

JPQL에서 ON 조건절은 조인 조건을 지정하는 곳이므로, 비교 연산자 등을 활용해서 조건 입력

    - ON 조건절에 = 비교 연산자 추가

 

👉 기본 환경

- Language: Java

- DB: H2 Database

- IDE: IntelliJ

 

 

⌨️ 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class Main {
    public static void main(String[] args) {
 
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
 
        EntityManager em = emf.createEntityManager();
 
        EntityTransaction tx = em.getTransaction();
        tx.begin(); // transaction 시작 선언
 
        try {
            Member member1 = new Member();
            member1.setName("Member1");
            em.persist(member1);
 
            Member member2 = new Member();
            member2.setName("Member1");
            em.persist(member2);
 
            // Scala Type Projection
            em.createQuery("select distinct m.name, m.age from Member m", Order.class)
                    .getResultList();
 
            tx.commit(); // transaction 종료 후 commit
        } catch (Exception e) {
            tx.rollback(); // 문제가 생길 경우, rollback 진행
            e.printStackTrace();
        } finally {
            em.close(); // tx에 문제가 생기더라도 em 반드시 종료
        }
 
        emf.close();
 
    }
}
 
 

 

 

🖨️오류

1
2
3
4
5
6
java.lang.IllegalArgumentException: Cannot create TypedQuery for query with more than one return using requested result type [jpql.Order]
    at org.hibernate.internal.AbstractSharedSessionContract.resultClassChecking(AbstractSharedSessionContract.java:870)
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:817)
    at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:23)
    at jpql.Main.main(Main.java:54)
 
 

 

 

📡 원인

return type이 불일치

 

 

📰 해결 방법

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class Main {
    public static void main(String[] args) {
 
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
 
        EntityManager em = emf.createEntityManager();
 
        EntityTransaction tx = em.getTransaction();
        tx.begin(); // transaction 시작 선언
 
        try {
            Member member1 = new Member();
            member1.setName("Member1");
            em.persist(member1);
 
            Member member2 = new Member();
            member2.setName("Member1");
            em.persist(member2);
 
            // Scala Type Projection
            em.createQuery("select distinct m.name, m.age from Member m")
                    .getResultList();
 
            tx.commit(); // transaction 종료 후 commit
        } catch (Exception e) {
            tx.rollback(); // 문제가 생길 경우, rollback 진행
            e.printStackTrace();
        } finally {
            em.close(); // tx에 문제가 생기더라도 em 반드시 종료
        }
 
        emf.close();
 
    }
}
 
 

return 타입 생략

 

👉 기본 환경

- Language: Java

- DB: H2 Database

- IDE: IntelliJ

 

 

⌨️ 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class Main {
    public static void main(String[] args) {
 
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
 
        EntityManager em = emf.createEntityManager();
 
        EntityTransaction tx = em.getTransaction();
        tx.begin(); // transaction 시작 선언
 
        try {
            Member member1 = new Member();
            member1.setName("Member1");
            em.persist(member1);
 
            Member member2 = new Member();
            member2.setName("Member1");
            em.persist(member2);
 
            TypedQuery<Member> query = em.createQuery("select m from Member m where m.name='Member1'", Member.class);
            Member member = query.getSingleResult();
 
            tx.commit(); // transaction 종료 후 commit
        } catch (Exception e) {
            tx.rollback(); // 문제가 생길 경우, rollback 진행
            e.printStackTrace();
        } finally {
            em.close(); // tx에 문제가 생기더라도 em 반드시 종료
        }
 
        emf.close();
 
    }
}
 
 

 

 

🖨️오류

1
2
3
4
5
javax.persistence.NonUniqueResultException: query did not return a unique result: 2
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:128)
    at org.hibernate.query.internal.AbstractProducedQuery.getSingleResult(AbstractProducedQuery.java:1588)
    at jpql.Main.main(Main.java:30)
 
 

 

 

📡 원인

getSingleResult()의 result가 2개 이상

 

 

📰 해결 방법

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class Main {
    public static void main(String[] args) {
 
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
 
        EntityManager em = emf.createEntityManager();
 
        EntityTransaction tx = em.getTransaction();
        tx.begin(); // transaction 시작 선언
 
        try {
            Member member1 = new Member();
            member1.setName("Member1");
            em.persist(member1);
 
            Member member2 = new Member();
            member2.setName("Member1");
            em.persist(member2);
 
            TypedQuery<Member> query = em.createQuery("select m from Member m where m.name='Member1'", Member.class);
            List<Member> resultList = query.getResultList();
 
            tx.commit(); // transaction 종료 후 commit
        } catch (Exception e) {
            tx.rollback(); // 문제가 생길 경우, rollback 진행
            e.printStackTrace();
        } finally {
            em.close(); // tx에 문제가 생기더라도 em 반드시 종료
        }
 
        emf.close();
 
    }
}
 
 

Exception 방지를 위해 getResultList() 사용