Skip to content

Commit 46cc679

Browse files
authored
Refine ID value handling and improve type constraints. (#1299)
2 parents 91143bb + 6ea9084 commit 46cc679

File tree

11 files changed

+274
-3
lines changed

11 files changed

+274
-3
lines changed

doma-core/src/main/java/org/seasar/doma/jdbc/dialect/Dialect.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ public interface Dialect {
9393
/**
9494
* Determines if the identity column is included based on the provided identifier value.
9595
*
96+
* <p>The type of {@code idValue} must be one of the basic types. It must never be a domain class
97+
* or an Optional type that wraps a basic type.
98+
*
9699
* @param idValue an identity value; may be null
97100
* @return true if the identity column is included, false otherwise
98101
*/

doma-core/src/main/java/org/seasar/doma/jdbc/id/IdGenerator.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ public interface IdGenerator {
6262
* Determines whether the identity column is included in the SQL INSERT statements based on the
6363
* given configuration and identity value.
6464
*
65+
* <p>The type of {@code idValue} must be one of the basic types. It must never be a domain class
66+
* or an Optional type that wraps a basic type.
67+
*
6568
* @param config the configuration for identity generation
6669
* @param idValue an identity value; may be null
6770
* @return {@code true} if the identity column is included in the SQL INSERT statements, otherwise

doma-core/src/main/java/org/seasar/doma/jdbc/query/AutoBatchInsertQuery.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ protected void prepareTargetPropertyTypes() {
142142
Property<ENTITY, ?> property = propertyType.createProperty();
143143
property.load(currentEntity);
144144
if (propertyType != generatedIdPropertyType
145-
|| generatedIdPropertyType.isIncluded(idGenerationConfig, property.get())) {
145+
|| generatedIdPropertyType.isIncluded(
146+
idGenerationConfig, property.getWrapper().get())) {
146147
targetPropertyTypes.add(propertyType);
147148
}
148149
if (generatedIdPropertyType == null) {

doma-core/src/main/java/org/seasar/doma/jdbc/query/AutoInsertQuery.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ protected void prepareTargetPropertyType() {
102102
property.load(entity);
103103
if (propertyType.isId()) {
104104
if (propertyType != generatedIdPropertyType
105-
|| generatedIdPropertyType.isIncluded(idGenerationConfig, property.get())) {
105+
|| generatedIdPropertyType.isIncluded(
106+
idGenerationConfig, property.getWrapper().get())) {
106107
targetPropertyTypes.add(propertyType);
107108
}
108109
if (generatedIdPropertyType == null && property.getWrapper().get() == null) {

doma-core/src/main/java/org/seasar/doma/jdbc/query/AutoMultiInsertQuery.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ protected void prepareTargetPropertyType() {
124124
property.load(entity);
125125
if (propertyType.isId()) {
126126
if (propertyType != generatedIdPropertyType
127-
|| generatedIdPropertyType.isIncluded(idGenerationConfig, property.get())) {
127+
|| generatedIdPropertyType.isIncluded(
128+
idGenerationConfig, property.getWrapper().get())) {
128129
targetPropertyTypes.add(propertyType);
129130
}
130131
if (generatedIdPropertyType == null && property.getWrapper().get() == null) {
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright Doma 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.seasar.doma.it.dao;
17+
18+
import java.util.List;
19+
import org.seasar.doma.BatchInsert;
20+
import org.seasar.doma.Dao;
21+
import org.seasar.doma.Insert;
22+
import org.seasar.doma.MultiInsert;
23+
import org.seasar.doma.Select;
24+
import org.seasar.doma.it.entity.OptionalIdentityStrategy;
25+
26+
@Dao
27+
public interface OptionalIdentityStrategyDao {
28+
29+
@Select
30+
List<OptionalIdentityStrategy> selectAll();
31+
32+
@Insert
33+
int insert(OptionalIdentityStrategy entity);
34+
35+
@BatchInsert
36+
int[] insert(List<OptionalIdentityStrategy> entities);
37+
38+
@MultiInsert
39+
int insertMultiRows(List<OptionalIdentityStrategy> entities);
40+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright Doma 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.seasar.doma.it.entity;
17+
18+
import java.util.Optional;
19+
import org.seasar.doma.Column;
20+
import org.seasar.doma.Entity;
21+
import org.seasar.doma.GeneratedValue;
22+
import org.seasar.doma.GenerationType;
23+
import org.seasar.doma.Id;
24+
import org.seasar.doma.OriginalStates;
25+
import org.seasar.doma.Table;
26+
27+
@Entity
28+
@Table(name = "IDENTITY_STRATEGY")
29+
public class OptionalIdentityStrategy {
30+
31+
@Id
32+
@GeneratedValue(strategy = GenerationType.IDENTITY)
33+
Optional<Integer> id;
34+
35+
@Column(quote = true)
36+
Integer value;
37+
38+
@OriginalStates OptionalIdentityStrategy originalStates;
39+
40+
public Optional<Integer> getId() {
41+
return id;
42+
}
43+
44+
public void setId(Optional<Integer> id) {
45+
this.id = id;
46+
}
47+
48+
public Integer getValue() {
49+
return value;
50+
}
51+
52+
public void setValue(Integer value) {
53+
this.value = value;
54+
}
55+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
select * from IDENTITY_STRATEGY

integration-test-java/src/test/java/org/seasar/doma/it/auto/AutoBatchInsertTest.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@
4949
import org.seasar.doma.it.dao.IdentityStrategyDaoImpl;
5050
import org.seasar.doma.it.dao.NoIdDao;
5151
import org.seasar.doma.it.dao.NoIdDaoImpl;
52+
import org.seasar.doma.it.dao.OptionalIdentityStrategyDao;
53+
import org.seasar.doma.it.dao.OptionalIdentityStrategyDaoImpl;
5254
import org.seasar.doma.it.dao.SequenceStrategyDao;
5355
import org.seasar.doma.it.dao.SequenceStrategyDaoImpl;
5456
import org.seasar.doma.it.dao.StaffDao;
@@ -69,6 +71,7 @@
6971
import org.seasar.doma.it.entity.IdentityStrategy;
7072
import org.seasar.doma.it.entity.IdentityStrategy2;
7173
import org.seasar.doma.it.entity.NoId;
74+
import org.seasar.doma.it.entity.OptionalIdentityStrategy;
7275
import org.seasar.doma.it.entity.SequenceStrategy;
7376
import org.seasar.doma.it.entity.Staff;
7477
import org.seasar.doma.it.entity.TableStrategy;
@@ -273,6 +276,63 @@ public void testId_Identity_ignoreGeneratedKeys(Config config) {
273276
assertEquals(220, list.size());
274277
}
275278

279+
@Test
280+
@Run(unless = {Dbms.ORACLE, Dbms.SQLSERVER})
281+
public void testId_OptionalIdentity_override(Config config) {
282+
IdentityOverridableConfig newConfig = new IdentityOverridableConfig(config);
283+
OptionalIdentityStrategyDao dao = new OptionalIdentityStrategyDaoImpl(newConfig);
284+
for (int i = 0; i < 110; i++) {
285+
OptionalIdentityStrategy entity = new OptionalIdentityStrategy();
286+
entity.setId(Optional.of(1000 + i));
287+
OptionalIdentityStrategy entity2 = new OptionalIdentityStrategy();
288+
entity2.setId(Optional.of(2000 + i));
289+
int[] result = dao.insert(Arrays.asList(entity, entity2));
290+
assertEquals(2, result.length);
291+
assertEquals(1, result[0]);
292+
assertEquals(1, result[1]);
293+
assertNotNull(entity.getId());
294+
assertNotNull(entity2.getId());
295+
}
296+
var expected =
297+
IntStream.concat(IntStream.rangeClosed(1000, 1109), IntStream.rangeClosed(2000, 2109))
298+
.boxed()
299+
.toList();
300+
var actual =
301+
dao.selectAll().stream()
302+
.map(OptionalIdentityStrategy::getId)
303+
.filter(Optional::isPresent)
304+
.map(Optional::get)
305+
.sorted()
306+
.toList();
307+
assertEquals(expected, actual);
308+
}
309+
310+
@Test
311+
@Run(unless = {Dbms.ORACLE})
312+
public void testId_OptionalIdentity_dontOverride(Config config) {
313+
IdentityOverridableConfig newConfig = new IdentityOverridableConfig(config);
314+
OptionalIdentityStrategyDao dao = new OptionalIdentityStrategyDaoImpl(newConfig);
315+
for (int i = 0; i < 110; i++) {
316+
OptionalIdentityStrategy entity = new OptionalIdentityStrategy();
317+
OptionalIdentityStrategy entity2 = new OptionalIdentityStrategy();
318+
int[] result = dao.insert(Arrays.asList(entity, entity2));
319+
assertEquals(2, result.length);
320+
assertEquals(1, result[0]);
321+
assertEquals(1, result[1]);
322+
assertNotNull(entity.getId());
323+
assertNotNull(entity2.getId());
324+
}
325+
var expected = IntStream.rangeClosed(1, 220).boxed().toList();
326+
var actual =
327+
dao.selectAll().stream()
328+
.map(OptionalIdentityStrategy::getId)
329+
.filter(Optional::isPresent)
330+
.map(Optional::get)
331+
.sorted()
332+
.toList();
333+
assertEquals(expected, actual);
334+
}
335+
276336
@Test
277337
@Run(unless = {Dbms.MYSQL, Dbms.MYSQL8, Dbms.SQLSERVER, Dbms.SQLITE})
278338
public void testId_sequence(Config config) {

integration-test-java/src/test/java/org/seasar/doma/it/auto/AutoInsertTest.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@
5252
import org.seasar.doma.it.dao.IdentityStrategyDaoImpl;
5353
import org.seasar.doma.it.dao.NoIdDao;
5454
import org.seasar.doma.it.dao.NoIdDaoImpl;
55+
import org.seasar.doma.it.dao.OptionalIdentityStrategyDao;
56+
import org.seasar.doma.it.dao.OptionalIdentityStrategyDaoImpl;
5557
import org.seasar.doma.it.dao.PrimitiveIdentityStrategyDao;
5658
import org.seasar.doma.it.dao.PrimitiveIdentityStrategyDaoImpl;
5759
import org.seasar.doma.it.dao.SequenceStrategyDao;
@@ -74,6 +76,7 @@
7476
import org.seasar.doma.it.entity.IdentityStrategy;
7577
import org.seasar.doma.it.entity.IdentityStrategy2;
7678
import org.seasar.doma.it.entity.NoId;
79+
import org.seasar.doma.it.entity.OptionalIdentityStrategy;
7780
import org.seasar.doma.it.entity.PrimitiveIdentityStrategy;
7881
import org.seasar.doma.it.entity.SequenceStrategy;
7982
import org.seasar.doma.it.entity.Staff;
@@ -255,6 +258,49 @@ public void testId_Identity_dontOverride(Config config) {
255258
assertEquals(expected, actual);
256259
}
257260

261+
@Test
262+
@Run(unless = {Dbms.SQLSERVER})
263+
public void testId_OptionalIdentity_override(Config config) {
264+
Config newConfig = new IdentityOverridableConfig(config);
265+
OptionalIdentityStrategyDao dao = new OptionalIdentityStrategyDaoImpl(newConfig);
266+
for (int i = 0; i < 110; i++) {
267+
OptionalIdentityStrategy entity = new OptionalIdentityStrategy();
268+
entity.setId(Optional.of(1000 + i));
269+
dao.insert(entity);
270+
assertNotNull(entity.getId());
271+
}
272+
var expected = IntStream.rangeClosed(1000, 1109).boxed().toList();
273+
var actual =
274+
dao.selectAll().stream()
275+
.map(OptionalIdentityStrategy::getId)
276+
.filter(Optional::isPresent)
277+
.map(Optional::get)
278+
.sorted()
279+
.toList();
280+
assertEquals(expected, actual);
281+
}
282+
283+
@Test
284+
@Run(unless = {Dbms.SQLSERVER})
285+
public void testId_OptionalIdentity_dontOverride(Config config) {
286+
Config newConfig = new IdentityOverridableConfig(config);
287+
OptionalIdentityStrategyDao dao = new OptionalIdentityStrategyDaoImpl(newConfig);
288+
for (int i = 0; i < 110; i++) {
289+
OptionalIdentityStrategy entity = new OptionalIdentityStrategy();
290+
dao.insert(entity);
291+
assertNotNull(entity.getId());
292+
}
293+
var expected = IntStream.rangeClosed(1, 110).boxed().toList();
294+
var actual =
295+
dao.selectAll().stream()
296+
.map(OptionalIdentityStrategy::getId)
297+
.filter(Optional::isPresent)
298+
.map(Optional::get)
299+
.sorted()
300+
.toList();
301+
assertEquals(expected, actual);
302+
}
303+
258304
@Test
259305
public void testId_PrimitiveIdentity(Config config) {
260306
PrimitiveIdentityStrategyDao dao = new PrimitiveIdentityStrategyDaoImpl(config);

0 commit comments

Comments
 (0)