Skip to content

Commit 6d18873

Browse files
committed
Failing test involving Oracle's multiple result sets
a.k.a. implicit cursor ? https://stackoverflow.com/q/42091653/1261766
1 parent 1c21b8d commit 6d18873

File tree

8 files changed

+446
-0
lines changed

8 files changed

+446
-0
lines changed

pom.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,12 @@
204204
<version>9.1.0</version>
205205
<scope>test</scope>
206206
</dependency>
207+
<dependency>
208+
<groupId>com.oracle.database.jdbc</groupId>
209+
<artifactId>ojdbc8</artifactId>
210+
<version>23.6.0.24.10</version>
211+
<scope>test</scope>
212+
</dependency>
207213
<dependency>
208214
<groupId>org.assertj</groupId>
209215
<artifactId>assertj-core</artifactId>
@@ -254,6 +260,12 @@
254260
<version>${testcontainers.version}</version>
255261
<scope>test</scope>
256262
</dependency>
263+
<dependency>
264+
<groupId>org.testcontainers</groupId>
265+
<artifactId>oracle-free</artifactId>
266+
<version>${testcontainers.version}</version>
267+
<scope>test</scope>
268+
</dependency>
257269
<!-- For javadoc link -->
258270
<dependency>
259271
<groupId>com.microsoft.sqlserver</groupId>
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* Copyright 2009-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.apache.ibatis.submitted.oracle_implicit_cursor;
18+
19+
import java.util.List;
20+
import java.util.Objects;
21+
22+
public class Author {
23+
private Integer id;
24+
private String name;
25+
private List<Book> books;
26+
27+
public Author() {
28+
super();
29+
}
30+
31+
public Author(Integer id, String name, List<Book> books) {
32+
super();
33+
this.id = id;
34+
this.name = name;
35+
this.books = books;
36+
}
37+
38+
public Integer getId() {
39+
return id;
40+
}
41+
42+
public void setId(Integer id) {
43+
this.id = id;
44+
}
45+
46+
public String getName() {
47+
return name;
48+
}
49+
50+
public void setName(String name) {
51+
this.name = name;
52+
}
53+
54+
public List<Book> getBooks() {
55+
return books;
56+
}
57+
58+
public void setBooks(List<Book> books) {
59+
this.books = books;
60+
}
61+
62+
@Override
63+
public int hashCode() {
64+
return Objects.hash(books, id, name);
65+
}
66+
67+
@Override
68+
public boolean equals(Object obj) {
69+
if (this == obj) {
70+
return true;
71+
}
72+
if (!(obj instanceof Author)) {
73+
return false;
74+
}
75+
Author other = (Author) obj;
76+
return Objects.equals(books, other.books) && Objects.equals(id, other.id) && Objects.equals(name, other.name);
77+
}
78+
79+
@Override
80+
public String toString() {
81+
return "Author [id=" + id + ", name=" + name + ", books=" + books + "]";
82+
}
83+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Copyright 2009-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.apache.ibatis.submitted.oracle_implicit_cursor;
18+
19+
import java.util.Objects;
20+
21+
public class Book {
22+
private Integer id;
23+
private String name;
24+
25+
public Book() {
26+
super();
27+
}
28+
29+
public Book(Integer id, String name) {
30+
super();
31+
this.id = id;
32+
this.name = name;
33+
}
34+
35+
public Integer getId() {
36+
return id;
37+
}
38+
39+
public void setId(Integer id) {
40+
this.id = id;
41+
}
42+
43+
public String getName() {
44+
return name;
45+
}
46+
47+
public void setName(String name) {
48+
this.name = name;
49+
}
50+
51+
@Override
52+
public int hashCode() {
53+
return Objects.hash(id, name);
54+
}
55+
56+
@Override
57+
public boolean equals(Object obj) {
58+
if (this == obj) {
59+
return true;
60+
}
61+
if (!(obj instanceof Book)) {
62+
return false;
63+
}
64+
Book other = (Book) obj;
65+
return Objects.equals(id, other.id) && Objects.equals(name, other.name);
66+
}
67+
68+
@Override
69+
public String toString() {
70+
return "Book [id=" + id + ", name=" + name + "]";
71+
}
72+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright 2009-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.apache.ibatis.submitted.oracle_implicit_cursor;
17+
18+
import java.util.List;
19+
20+
public interface Mapper {
21+
22+
List<Author> selectImplicitCursors_Statement();
23+
24+
List<Author> selectImplicitCursors_Prepared();
25+
26+
List<Author> selectImplicitCursors_Callable();
27+
28+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Copyright 2009-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.apache.ibatis.submitted.oracle_implicit_cursor;
17+
18+
import static org.junit.jupiter.api.Assertions.assertIterableEquals;
19+
20+
import java.util.List;
21+
import java.util.function.Function;
22+
23+
import org.apache.ibatis.BaseDataTest;
24+
import org.apache.ibatis.mapping.Environment;
25+
import org.apache.ibatis.session.Configuration;
26+
import org.apache.ibatis.session.SqlSession;
27+
import org.apache.ibatis.session.SqlSessionFactory;
28+
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
29+
import org.apache.ibatis.testcontainers.OracleTestContainer;
30+
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
31+
import org.junit.jupiter.api.BeforeAll;
32+
import org.junit.jupiter.api.Tag;
33+
import org.junit.jupiter.api.Test;
34+
35+
@Tag("TestcontainersTests")
36+
class OracleImplicitCursorTest {
37+
38+
private static SqlSessionFactory sqlSessionFactory;
39+
40+
@BeforeAll
41+
static void setUp() throws Exception {
42+
Configuration configuration = new Configuration();
43+
Environment environment = new Environment("development", new JdbcTransactionFactory(),
44+
OracleTestContainer.getUnpooledDataSource());
45+
configuration.setEnvironment(environment);
46+
configuration.addMapper(Mapper.class);
47+
sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
48+
49+
BaseDataTest.runScript(sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(),
50+
"org/apache/ibatis/submitted/oracle_implicit_cursor/CreateDB.sql");
51+
}
52+
53+
@Test
54+
void shouldImplicitCursors_Statement() {
55+
doTest(Mapper::selectImplicitCursors_Statement);
56+
}
57+
58+
@Test
59+
void shouldImplicitCursors_Prepared() {
60+
doTest(Mapper::selectImplicitCursors_Prepared);
61+
}
62+
63+
@Test
64+
void shouldImplicitCursors_Callable() {
65+
doTest(Mapper::selectImplicitCursors_Callable);
66+
}
67+
68+
private void doTest(Function<Mapper, List<Author>> query) {
69+
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
70+
Mapper mapper = sqlSession.getMapper(Mapper.class);
71+
List<Author> authors = query.apply(mapper);
72+
assertIterableEquals(
73+
List.of(new Author(1, "John", List.of(new Book(1, "C#"), new Book(2, "Python"), new Book(5, "Ruby"))),
74+
new Author(2, "Jane", List.of(new Book(3, "SQL"), new Book(4, "Java")))),
75+
authors);
76+
}
77+
}
78+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright 2009-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.apache.ibatis.testcontainers;
17+
18+
import javax.sql.DataSource;
19+
20+
import org.apache.ibatis.datasource.pooled.PooledDataSource;
21+
import org.apache.ibatis.datasource.unpooled.UnpooledDataSource;
22+
import org.testcontainers.junit.jupiter.Container;
23+
import org.testcontainers.junit.jupiter.Testcontainers;
24+
import org.testcontainers.oracle.OracleContainer;
25+
26+
@Testcontainers
27+
public final class OracleTestContainer {
28+
29+
private static final String DB_NAME = "mybatis_test";
30+
private static final String USERNAME = "u";
31+
private static final String PASSWORD = "p";
32+
private static final String DRIVER = "oracle.jdbc.driver.OracleDriver";
33+
34+
@Container
35+
private static final OracleContainer INSTANCE = initContainer();
36+
37+
private static OracleContainer initContainer() {
38+
@SuppressWarnings("resource")
39+
var container = new OracleContainer("gvenzl/oracle-free:slim-faststart").withDatabaseName(DB_NAME)
40+
.withUsername(USERNAME).withPassword(PASSWORD);
41+
container.start();
42+
return container;
43+
}
44+
45+
public static DataSource getUnpooledDataSource() {
46+
return new UnpooledDataSource(OracleTestContainer.DRIVER, INSTANCE.getJdbcUrl(), OracleTestContainer.USERNAME,
47+
OracleTestContainer.PASSWORD);
48+
}
49+
50+
public static PooledDataSource getPooledDataSource() {
51+
return new PooledDataSource(OracleTestContainer.DRIVER, INSTANCE.getJdbcUrl(), OracleTestContainer.USERNAME,
52+
OracleTestContainer.PASSWORD);
53+
}
54+
55+
private OracleTestContainer() {
56+
}
57+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
--
2+
-- Copyright 2009-2025 the original author or authors.
3+
--
4+
-- Licensed under the Apache License, Version 2.0 (the "License");
5+
-- you may not use this file except in compliance with the License.
6+
-- You may obtain a copy of the License at
7+
--
8+
-- https://www.apache.org/licenses/LICENSE-2.0
9+
--
10+
-- Unless required by applicable law or agreed to in writing, software
11+
-- distributed under the License is distributed on an "AS IS" BASIS,
12+
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
-- See the License for the specific language governing permissions and
14+
-- limitations under the License.
15+
--
16+
17+
-- @DELIMITER |
18+
begin
19+
execute immediate 'drop table author';
20+
exception
21+
when others then
22+
if sqlcode != -942 then
23+
raise;
24+
end if;
25+
end;
26+
begin
27+
execute immediate 'drop table book';
28+
exception
29+
when others then
30+
if sqlcode != -942 then
31+
raise;
32+
end if;
33+
end;
34+
|
35+
-- @DELIMITER ;
36+
37+
create table author (id int, name varchar(10));
38+
39+
insert into author (id, name) values (1, 'John');
40+
insert into author (id, name) values (2, 'Jane');
41+
42+
43+
create table book (id int, author_id int, name varchar(10));
44+
45+
insert into book (id, author_id, name) values (1, 1, 'C#');
46+
insert into book (id, author_id, name) values (2, 1, 'Python');
47+
insert into book (id, author_id, name) values (3, 2, 'SQL');
48+
insert into book (id, author_id, name) values (4, 2, 'Java');
49+
insert into book (id, author_id, name) values (5, 1, 'Ruby');

0 commit comments

Comments
 (0)