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

mybatis / generator / 2135

02 Apr 2026 05:50PM UTC coverage: 91.765% (+1.4%) from 90.382%
2135

Pull #1485

github

web-flow
Merge a9306dd47 into 18f1f002d
Pull Request #1485: Code Cleanup and Coverage

2425 of 3126 branches covered (77.58%)

134 of 172 new or added lines in 28 files covered. (77.91%)

7 existing lines in 4 files now uncovered.

11879 of 12945 relevant lines covered (91.77%)

0.92 hits per line

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

61.31
/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.messages.Messages.getString;
20

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

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

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

78
    private final List<GenerationResults> generationResultsList = new ArrayList<>();
1✔
79

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

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

95
        isOverwriteEnabled = builder.isOverwriteEnabled;
1✔
96
    }
1✔
97

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

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

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

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

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

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

175
        return contextsToRun;
1✔
176
    }
177

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

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

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

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

206
        return contextValuesAndTablesList;
1✔
207
    }
208

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

338
    /**
339
     * Writes, or overwrites, the contents of the specified file.
340
     *
341
     * @param file
342
     *            the file
343
     * @param content
344
     *            the content
345
     * @param fileEncoding
346
     *            the file encoding
347
     * @throws IOException
348
     *             Signals that an I/O exception has occurred.
349
     */
350
    private void writeFile(File file, String content, @Nullable String fileEncoding) throws IOException {
351
        try (OutputStream fos = Files.newOutputStream(file.toPath(), StandardOpenOption.CREATE,
×
352
                StandardOpenOption.TRUNCATE_EXISTING)) {
353
            OutputStreamWriter osw;
354
            if (fileEncoding == null) {
×
355
                osw = new OutputStreamWriter(fos);
×
356
            } else {
357
                osw = new OutputStreamWriter(fos, Charset.forName(fileEncoding));
×
358
            }
359

360
            try (BufferedWriter bw = new BufferedWriter(osw)) {
×
361
                bw.write(content);
×
362
            }
363
        }
364
    }
×
365

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

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

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

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

397
        return answer;
×
398
    }
399

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

553
        public MyBatisGenerator build() {
554
            return new MyBatisGenerator(this);
1✔
555
        }
556
    }
557
}
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