• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mybatis / generator / 2141

06 Apr 2026 03:11PM UTC coverage: 91.678% (-0.1%) from 91.775%
2141

Pull #1487

github

web-flow
Merge f4ea84243 into 7c7d0387c
Pull Request #1487: Add a new exception for merge errors, improve exception handling in general

2425 of 3124 branches covered (77.62%)

19 of 44 new or added lines in 13 files covered. (43.18%)

7 existing lines in 4 files now uncovered.

11887 of 12966 relevant lines covered (91.68%)

0.92 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

60.7
/core/mybatis-generator-core/src/main/java/org/mybatis/generator/api/MyBatisGenerator.java
1
/*
2
 *    Copyright 2006-2026 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.mybatis.generator.api;
17

18
import static org.mybatis.generator.internal.util.ClassloaderUtility.getCustomClassloader;
19
import static org.mybatis.generator.internal.util.StringUtility.mapStringValueOrElseGet;
20
import static org.mybatis.generator.internal.util.messages.Messages.getString;
21

22
import java.io.BufferedWriter;
23
import java.io.File;
24
import java.io.IOException;
25
import java.io.OutputStream;
26
import java.io.OutputStreamWriter;
27
import java.nio.charset.Charset;
28
import java.nio.file.Files;
29
import java.nio.file.Path;
30
import java.nio.file.StandardOpenOption;
31
import java.sql.SQLException;
32
import java.util.ArrayList;
33
import java.util.Collection;
34
import java.util.HashSet;
35
import java.util.List;
36
import java.util.Objects;
37
import java.util.Set;
38

39
import org.jspecify.annotations.Nullable;
40
import org.mybatis.generator.codegen.CalculatedContextValues;
41
import org.mybatis.generator.codegen.GenerationEngine;
42
import org.mybatis.generator.codegen.GenerationResults;
43
import org.mybatis.generator.codegen.IntrospectionEngine;
44
import org.mybatis.generator.codegen.RootClassInfo;
45
import org.mybatis.generator.config.Configuration;
46
import org.mybatis.generator.config.Context;
47
import org.mybatis.generator.exception.InternalException;
48
import org.mybatis.generator.exception.InvalidConfigurationException;
49
import org.mybatis.generator.exception.MergeException;
50
import org.mybatis.generator.exception.ShellException;
51
import org.mybatis.generator.internal.DefaultShellCallback;
52
import org.mybatis.generator.internal.ObjectFactory;
53
import org.mybatis.generator.merge.java.JavaFileMerger;
54
import org.mybatis.generator.merge.java.JavaMergerFactory;
55
import org.mybatis.generator.merge.xml.XmlFileMergerJaxp;
56

57
/**
58
 * This class is the main interface to MyBatis generator. A typical execution of the tool involves these steps:
59
 * <ol>
60
 * <li>Create a Configuration object. The Configuration can be the result of a parsing the XML configuration file, or it
61
 * can be created solely in Java.</li>
62
 * <li>Create a MyBatisGenerator object</li>
63
 * <li>Call one of the generate() methods</li>
64
 * </ol>
65
 *
66
 * @author Jeff Butler
67
 *
68
 * @see org.mybatis.generator.config.xml.ConfigurationParser
69
 */
70
public class MyBatisGenerator {
71
    private final Configuration configuration;
72
    private final ShellCallback shellCallback;
73
    private final ProgressCallback progressCallback;
74
    private final Set<String> contextIds;
75
    private final Set<String> fullyQualifiedTableNames;
76
    private final JavaFileMerger javaFileMerger;
77
    private final boolean isOverwriteEnabled;
78
    private final boolean isJavaFileMergeEnabled;
79

80
    private final List<GenerationResults> generationResultsList = new ArrayList<>();
1✔
81

82
    private MyBatisGenerator(Builder builder) {
1✔
83
        configuration = Objects.requireNonNull(builder.configuration, getString("RuntimeError.2")); //$NON-NLS-1$
1✔
84
        shellCallback = Objects.requireNonNullElseGet(builder.shellCallback, DefaultShellCallback::new);
1✔
85
        progressCallback = Objects.requireNonNullElseGet(builder.progressCallback, () -> new ProgressCallback() {});
1✔
86
        fullyQualifiedTableNames = builder.fullyQualifiedTableNames;
1✔
87
        contextIds = builder.contextIds;
1✔
88

89
        if (builder.isJavaFileMergeEnabled) {
1!
90
            isJavaFileMergeEnabled = true;
×
91
            javaFileMerger = JavaMergerFactory.getMerger(JavaMergerFactory.PrinterConfiguration.LEXICAL_PRESERVING);
×
92
        } else {
93
            isJavaFileMergeEnabled = false;
1✔
94
            javaFileMerger = (newContent, existingContent) -> newContent;
1✔
95
        }
96

97
        isOverwriteEnabled = builder.isOverwriteEnabled;
1✔
98
    }
1✔
99

100
    /**
101
     * This is one of the main methods for generating code. This method is long-running, but progress can be provided
102
     * and the method can be canceled through the ProgressCallback interface. This method will not write results to
103
     * the disk. The generated objects can be retrieved from the getGeneratedJavaFiles(), getGeneratedKotlinFiles(),
104
     * getGeneratedXmlFiles(), and getGeneratedGenericFiles() methods.
105
     *
106
     * @return any warnings created during the generation process
107
     * @throws SQLException
108
     *             the SQL exception
109
     * @throws InterruptedException
110
     *             if the method is canceled through the ProgressCallback
111
     * @throws InvalidConfigurationException
112
     *             if the specified configuration is invalid
113
     */
114
    public List<String> generateOnly() throws SQLException, InterruptedException, InvalidConfigurationException {
115
        List<String> warnings = new ArrayList<>();
1✔
116
        generateFiles(warnings);
1✔
117
        progressCallback.done();
1✔
118
        return warnings;
1✔
119
    }
120

121
    /**
122
     * This is one of the main methods for generating code. This method is long-running, but progress can be provided
123
     * and the method can be canceled through the ProgressCallback interface. This method will write results to
124
     * the disk.
125
     *
126
     * @return any warnings created during the generation process
127
     * @throws SQLException
128
     *             the SQL exception
129
     * @throws IOException
130
     *             Signals that an I/O exception has occurred.
131
     * @throws InterruptedException
132
     *             if the method is canceled through the ProgressCallback
133
     * @throws InvalidConfigurationException
134
     *             if the specified configuration is invalid
135
     */
136
    public List<String> generateAndWrite() throws SQLException, IOException, InterruptedException,
137
            InvalidConfigurationException {
138
        List<String> warnings = new ArrayList<>();
1✔
139
        generateFiles(warnings);
1✔
140
        writeGeneratedFiles(warnings);
1✔
141
        progressCallback.done();
1✔
142
        return warnings;
1✔
143
    }
144

145
    private void generateFiles(List<String> warnings) throws SQLException, InterruptedException,
146
            InvalidConfigurationException {
147
        configuration.validate();
1✔
148
        generationResultsList.clear();
1✔
149
        ObjectFactory.reset();
1✔
150
        RootClassInfo.reset();
1✔
151

152
        setupCustomClassloader();
1✔
153
        List<Context> contextsToRun = calculateContextsToRun();
1✔
154
        List<CalculatedContextValues> contextValuesList = calculateContextValues(contextsToRun, warnings);
1✔
155
        List<ContextValuesAndTables> contextValuesAndTablesList = runAllIntrospections(contextValuesList, warnings);
1✔
156
        List<GenerationEngine> generationEngines = createGenerationEngines(contextValuesAndTablesList, warnings);
1✔
157
        runGenerationEngines(generationEngines);
1✔
158
    }
1✔
159

160
    private void setupCustomClassloader() {
161
        if (!configuration.getClassPathEntries().isEmpty()) {
1!
162
            ClassLoader classLoader = getCustomClassloader(configuration.getClassPathEntries());
×
163
            ObjectFactory.addExternalClassLoader(classLoader);
×
164
        }
165
    }
1✔
166

167
    private List<Context> calculateContextsToRun() {
168
        List<Context> contextsToRun;
169
        if (fullyQualifiedTableNames.isEmpty()) {
1!
170
            contextsToRun = configuration.getContexts();
1✔
171
        } else {
172
            contextsToRun = configuration.getContexts().stream()
×
173
                    .filter(c -> contextIds.contains(c.getId()))
×
174
                    .toList();
×
175
        }
176

177
        return contextsToRun;
1✔
178
    }
179

180
    private List<CalculatedContextValues> calculateContextValues(List<Context> contextsToRun, List<String> warnings) {
181
        return contextsToRun.stream()
1✔
182
                .map(c -> createContextValues(c, warnings))
1✔
183
                .toList();
1✔
184
    }
185

186
    private CalculatedContextValues createContextValues(Context context, List<String> warnings) {
187
        return new CalculatedContextValues.Builder()
1✔
188
                .withContext(context)
1✔
189
                .withWarnings(warnings)
1✔
190
                .build();
1✔
191
    }
192

193
    private List<ContextValuesAndTables> runAllIntrospections(List<CalculatedContextValues> contextValuesList,
194
                                                              List<String> warnings)
195
            throws SQLException, InterruptedException {
196
        int totalSteps = contextValuesList.stream()
1✔
197
                .map(CalculatedContextValues::context)
1✔
198
                .mapToInt(Context::getIntrospectionSteps)
1✔
199
                .sum();
1✔
200
        progressCallback.introspectionStarted(totalSteps);
1✔
201

202
        List<ContextValuesAndTables> contextValuesAndTablesList = new ArrayList<>();
1✔
203
        for (CalculatedContextValues contextValues : contextValuesList) {
1✔
204
            contextValuesAndTablesList.add(new ContextValuesAndTables(contextValues,
1✔
205
                    runContextIntrospection(fullyQualifiedTableNames, contextValues, warnings)));
1✔
206
        }
1✔
207

208
        return contextValuesAndTablesList;
1✔
209
    }
210

211
    private List<IntrospectedTable> runContextIntrospection(Set<String> fullyQualifiedTableNames,
212
                                                            CalculatedContextValues contextValues,
213
                                                            List<String> warnings)
214
            throws SQLException, InterruptedException {
215
        return new IntrospectionEngine.Builder()
1✔
216
                .withContextValues(contextValues)
1✔
217
                .withFullyQualifiedTableNames(fullyQualifiedTableNames)
1✔
218
                .withWarnings(warnings)
1✔
219
                .withProgressCallback(progressCallback)
1✔
220
                .build()
1✔
221
                .introspectTables();
1✔
222
    }
223

224
    private List<GenerationEngine> createGenerationEngines(List<ContextValuesAndTables> contextValuesAndTablesListList,
225
                                                           List<String> warnings) {
226
        return contextValuesAndTablesListList.stream()
1✔
227
                .map(c -> createGenerationEngine(c, warnings))
1✔
228
                .toList();
1✔
229
    }
230

231
    private GenerationEngine createGenerationEngine(ContextValuesAndTables contextValuesAndTables,
232
                                                    List<String> warnings) {
233
        return new GenerationEngine.Builder()
1✔
234
                .withContextValues(contextValuesAndTables.contextValues())
1✔
235
                .withProgressCallback(progressCallback)
1✔
236
                .withWarnings(warnings)
1✔
237
                .withIntrospectedTables(contextValuesAndTables.introspectedTables())
1✔
238
                .build();
1✔
239
    }
240

241
    private void runGenerationEngines(List<GenerationEngine> generationEngines) throws InterruptedException {
242
        // calculate the number of steps
243
        int totalSteps = generationEngines.stream().mapToInt(GenerationEngine::getGenerationSteps).sum();
1✔
244
        progressCallback.generationStarted(totalSteps);
1✔
245

246
        // now run the generators
247
        for (GenerationEngine generationEngine: generationEngines) {
1✔
248
            var generationResults = generationEngine.generate();
1✔
249
            generationResultsList.add(generationResults);
1✔
250
        }
1✔
251
    }
1✔
252

253
    private void writeGeneratedFiles(List<String> warnings) throws IOException, InterruptedException {
254
        Set<String> projects = new HashSet<>();
1✔
255
        int totalSteps = generationResultsList.stream().mapToInt(GenerationResults::getNumberOfGeneratedFiles).sum();
1✔
256
        progressCallback.saveStarted(totalSteps);
1✔
257

258
        for (GenerationResults generationResults : generationResultsList) {
1✔
259
            for (GeneratedXmlFile gxf : generationResults.generatedXmlFiles()) {
1!
260
                projects.add(gxf.getTargetProject());
×
261
                writeGeneratedXmlFile(gxf, generationResults.xmlFormatter(), warnings);
×
262
            }
×
263

264
            for (GeneratedJavaFile gjf : generationResults.generatedJavaFiles()) {
1!
265
                projects.add(gjf.getTargetProject());
×
266
                writeGeneratedJavaFile(gjf, generationResults.javaFormatter(), generationResults.javaFileEncoding(),
×
267
                        warnings);
268
            }
×
269

270
            for (GeneratedKotlinFile gkf : generationResults.generatedKotlinFiles()) {
1!
271
                projects.add(gkf.getTargetProject());
×
272
                writeGeneratedKotlinFile(gkf, generationResults.kotlinFormatter(),
×
273
                        generationResults.kotlinFileEncoding(), warnings);
×
274
            }
×
275

276
            for (GenericGeneratedFile gf : generationResults.generatedGenericFiles()) {
1!
277
                projects.add(gf.getTargetProject());
×
278
                writeGenericGeneratedFile(gf, warnings);
×
279
            }
×
280
        }
1✔
281

282
        for (String project : projects) {
1!
283
            shellCallback.refreshProject(project);
×
284
        }
×
285
    }
1✔
286

287
    private void writeGeneratedJavaFile(GeneratedJavaFile gf, JavaFormatter javaFormatter,
288
                                        @Nullable String javaFileEncoding, List<String> warnings)
289
            throws InterruptedException, IOException {
290
        String source = javaFormatter.getFormattedContent(gf.getCompilationUnit());
×
291
        writeFile(source, javaFileEncoding, gf, warnings, isJavaFileMergeEnabled,
×
292
                (newContent, existingContent) -> javaFileMerger.getMergedSource(newContent, existingContent,
×
293
                        javaFileEncoding));
294
    }
×
295

296
    private void writeGeneratedKotlinFile(GeneratedKotlinFile gf, KotlinFormatter kotlinFormatter,
297
                                          @Nullable String kotlinFileEncoding, List<String> warnings)
298
            throws InterruptedException, IOException {
299
        String source = kotlinFormatter.getFormattedContent(gf.getKotlinFile());
×
300
        writeFile(source, kotlinFileEncoding, gf, warnings, false, Merger.noMerge());
×
301
    }
×
302

303
    private void writeGenericGeneratedFile(GenericGeneratedFile gf, List<String> warnings)
304
            throws InterruptedException, IOException {
305
        String source = gf.getFormattedContent();
×
306
        writeFile(source, gf.getFileEncoding().orElse(null), gf, warnings, false, Merger.noMerge());
×
307
    }
×
308

309
    private void writeGeneratedXmlFile(GeneratedXmlFile gf, XmlFormatter xmlFormatter, List<String> warnings)
310
            throws InterruptedException, IOException {
311
        String source = xmlFormatter.getFormattedContent(gf.getDocument());
×
312
        writeFile(source, "UTF-8", gf, warnings, true, XmlFileMergerJaxp::getMergedSource); //$NON-NLS-1$
×
313
    }
×
314

315
    private void writeFile(String content, @Nullable String encoding, GeneratedFile gf, List<String> warnings,
316
                           boolean mergeEnabled, Merger merger)
317
            throws InterruptedException, IOException {
318
        try {
319
            File directory = shellCallback.getDirectory(gf.getTargetProject(), gf.getTargetPackage());
×
320
            Path targetFile = directory.toPath().resolve(gf.getFileName());
×
321
            if (Files.exists(targetFile)) {
×
322
                if (mergeEnabled && gf.isMergeable()) {
×
323
                    content = merger.apply(content, targetFile.toFile());
×
324
                } else if (isOverwriteEnabled) {
×
325
                    warnings.add(getString("Warning.11", targetFile.toFile().getAbsolutePath())); //$NON-NLS-1$
×
326
                } else {
327
                    targetFile = getUniqueFileName(directory, gf.getFileName());
×
328
                    warnings.add(getString("Warning.2", targetFile.toFile().getAbsolutePath())); //$NON-NLS-1$
×
329
                }
330
            }
331

332
            progressCallback.checkCancel();
×
333
            progressCallback.startTask(getString("Progress.15", targetFile.toString())); //$NON-NLS-1$
×
334
            writeFile(targetFile.toFile(), content, encoding);
×
335
        } catch (ShellException e) {
×
336
            warnings.add(e.getMessage());
×
NEW
337
        } catch (MergeException e) {
×
NEW
338
            warnings.add(e.getMessage());
×
NEW
339
            warnings.addAll(e.getExtraMessages());
×
340
        }
×
341
    }
×
342

343
    /**
344
     * Writes, or overwrites, the contents of the specified file.
345
     *
346
     * @param file
347
     *            the file
348
     * @param content
349
     *            the content
350
     * @param fileEncoding
351
     *            the file encoding
352
     * @throws IOException
353
     *             Signals that an I/O exception has occurred.
354
     */
355
    private void writeFile(File file, String content, @Nullable String fileEncoding) throws IOException {
356
        Charset cs = mapStringValueOrElseGet(fileEncoding, Charset::forName, Charset::defaultCharset);
×
357
        try (OutputStream outputStream = Files.newOutputStream(file.toPath(), StandardOpenOption.CREATE,
×
358
                StandardOpenOption.TRUNCATE_EXISTING)) {
359
            try (OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, cs)) {
×
360
                try (BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter)) {
×
361
                    bufferedWriter.write(content);
×
362
                }
363
            }
364
        }
365
    }
×
366

367
    /**
368
     * Gets the unique file name.
369
     *
370
     * @param directory
371
     *            the directory
372
     * @param fileName
373
     *            the file name
374
     * @return the unique file name
375
     */
376
    private Path getUniqueFileName(File directory, String fileName) {
377
        Path answer = null;
×
378

379
        // try up to 1000 times to generate a unique file name
380
        StringBuilder sb = new StringBuilder();
×
381
        for (int i = 1; i < 1000; i++) {
×
382
            sb.setLength(0);
×
383
            sb.append(fileName);
×
384
            sb.append('.');
×
385
            sb.append(i);
×
386

387
            Path testFile = directory.toPath().resolve(sb.toString());
×
388
            if (Files.notExists(testFile)) {
×
389
                answer = testFile;
×
390
                break;
×
391
            }
392
        }
393

394
        if (answer == null) {
×
395
            throw new InternalException(getString("RuntimeError.3", directory.getAbsolutePath())); //$NON-NLS-1$
×
396
        }
397

398
        return answer;
×
399
    }
400

401
    /**
402
     * Returns the list of generated Java files after a call to one of the generate methods.
403
     * This is useful if you prefer to process the generated files yourself and do not want
404
     * the generator to write them to disk.
405
     *
406
     * @return the list of generated Java files
407
     */
408
    public List<GeneratedJavaFile> getGeneratedJavaFiles() {
409
        return generationResultsList.stream()
1✔
410
                .map(GenerationResults::generatedJavaFiles)
1✔
411
                .flatMap(Collection::stream)
1✔
412
                .toList();
1✔
413
    }
414

415
    /**
416
     * Returns the list of generated Kotlin files after a call to one of the generate methods.
417
     * This is useful if you prefer to process the generated files yourself and do not want
418
     * the generator to write them to disk.
419
     *
420
     * @return the list of generated Kotlin files
421
     */
422
    public List<GeneratedKotlinFile> getGeneratedKotlinFiles() {
423
        return generationResultsList.stream()
1✔
424
                .map(GenerationResults::generatedKotlinFiles)
1✔
425
                .flatMap(Collection::stream)
1✔
426
                .toList();
1✔
427
    }
428

429
    /**
430
     * Returns the list of generated XML files after a call to one of the generate methods.
431
     * This is useful if you prefer to process the generated files yourself and do not want
432
     * the generator to write them to disk.
433
     *
434
     * @return the list of generated XML files
435
     */
436
    public List<GeneratedXmlFile> getGeneratedXmlFiles() {
437
        return generationResultsList.stream()
1✔
438
                .map(GenerationResults::generatedXmlFiles)
1✔
439
                .flatMap(Collection::stream)
1✔
440
                .toList();
1✔
441
    }
442

443
    /**
444
     * Returns the list of generated generic files after a call to one of the generate methods.
445
     * This is useful if you prefer to process the generated files yourself and do not want
446
     * the generator to write them to disk.
447
     *
448
     * <p>The list will be empty unless you have used a plugin that generates generic files
449
     * or are using a custom runtime.
450
     *
451
     * @return the list of generated generic files
452
     */
453
    public List<GenericGeneratedFile> getGeneratedGenericFiles() {
454
        return generationResultsList.stream()
×
455
                .map(GenerationResults::generatedGenericFiles)
×
456
                .flatMap(Collection::stream)
×
457
                .toList();
×
458
    }
459

460
    private record ContextValuesAndTables(CalculatedContextValues contextValues,
1✔
461
                                          List<IntrospectedTable> introspectedTables) { }
462

463
    @FunctionalInterface
464
    private interface Merger {
465
        String apply(String newContent, File existingContent) throws MergeException;
466

467
        static Merger noMerge() {
468
            return (newContent, existingContent) -> newContent;
×
469
        }
470
    }
471

472
    public static class Builder {
1✔
473
        private @Nullable Configuration configuration;
474
        private @Nullable ShellCallback shellCallback;
475
        private @Nullable ProgressCallback progressCallback;
476
        private final Set<String> contextIds = new HashSet<>();
1✔
477
        private final Set<String> fullyQualifiedTableNames = new HashSet<>();
1✔
478
        private boolean isOverwriteEnabled = false;
1✔
479
        private boolean isJavaFileMergeEnabled = false;
1✔
480

481
        public Builder withConfiguration(Configuration configuration) {
482
            this.configuration = configuration;
1✔
483
            return this;
1✔
484
        }
485

486
        public Builder withShellCallback(ShellCallback shellCallback) {
487
            this.shellCallback = shellCallback;
1✔
488
            return this;
1✔
489
        }
490

491
        public Builder withProgressCallback(@Nullable ProgressCallback progressCallback) {
492
            this.progressCallback = progressCallback;
1✔
493
            return this;
1✔
494
        }
495

496
        /**
497
         * Set of context IDs to use in generation. Only the contexts with an id specified in this set will run.
498
         * If the set is empty, then all contexts are run.
499
         *
500
         * @param contextIds
501
         *            a set of contextIds to use in code generation
502
         *
503
         * @return this builder
504
         */
505
        public Builder withContextIds(Set<String> contextIds) {
506
            this.contextIds.addAll(contextIds);
1✔
507
            return this;
1✔
508
        }
509

510
        /**
511
         *  Set of table names to generate. The elements of the set must be Strings that exactly match what's
512
         *  specified in the configuration. For example, if a table name = "foo" and schema = "bar", then the fully
513
         *  qualified table name is "foo.bar". If the Set is empty, then all tables in the configuration
514
         *  will be used for code generation.
515
         *
516
         * @param fullyQualifiedTableNames
517
         *            a set of table names to use in code generation
518
         *
519
         * @return this builder
520
         */
521
        public Builder withFullyQualifiedTableNames(Set<String> fullyQualifiedTableNames) {
522
            this.fullyQualifiedTableNames.addAll(fullyQualifiedTableNames);
1✔
523
            return this;
1✔
524
        }
525

526
        /**
527
         * If true, then newly generated files will overwrite existing files if there is a collision.
528
         * If false, then newly generated files will be written with a unique name when there is a collision.
529
         *
530
         * <p>The default is <code>false</code></p>
531
         *
532
         * @param overwriteEnabled where newly generated files should overwrite existing files if there is a collision
533
         * @return this builder
534
         */
535
        public Builder withOverwriteEnabled(boolean overwriteEnabled) {
536
            this.isOverwriteEnabled = overwriteEnabled;
1✔
537
            return this;
1✔
538
        }
539

540
        /**
541
         * If true, then newly generated Java files will be merged if they collide with existing files.
542
         * If false, then the {@link #withOverwriteEnabled(boolean)} value governs what happens on a collision.
543
         *
544
         * <p>The default is <code>false</code></p>
545
         *
546
         * @param javaFileMergeEnabled where the Java file merger support should be enabled
547
         * @return this builder
548
         */
549
        public Builder withJavaFileMergeEnabled(boolean javaFileMergeEnabled) {
550
            this.isJavaFileMergeEnabled = javaFileMergeEnabled;
1✔
551
            return this;
1✔
552
        }
553

554
        public MyBatisGenerator build() {
555
            return new MyBatisGenerator(this);
1✔
556
        }
557
    }
558
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc