├── .github └── workflows │ ├── ci.yml │ └── close-inactive-issues.yml ├── .gitignore ├── .mvn └── wrapper │ ├── MavenWrapperDownloader.java │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── README.md ├── doma-spring-boot-autoconfigure ├── pom.xml └── src │ ├── main │ ├── java │ │ └── org │ │ │ └── seasar │ │ │ └── doma │ │ │ └── boot │ │ │ └── autoconfigure │ │ │ ├── DomaAutoConfiguration.java │ │ │ ├── DomaConfig.java │ │ │ ├── DomaConfigBuilder.java │ │ │ ├── DomaProperties.java │ │ │ └── package-info.java │ └── resources │ │ └── META-INF │ │ ├── spring.factories │ │ └── spring │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports │ └── test │ └── java │ └── org │ └── seasar │ └── doma │ └── boot │ └── autoconfigure │ └── DomaAutoConfigurationTest.java ├── doma-spring-boot-core ├── pom.xml └── src │ ├── main │ └── java │ │ └── org │ │ └── seasar │ │ └── doma │ │ └── boot │ │ ├── ConfigAutowireable.java │ │ ├── DomaPersistenceExceptionTranslator.java │ │ ├── DomaSpringBootSqlBuilderSettings.java │ │ ├── Pageables.java │ │ ├── PropertyMetamodelResolver.java │ │ ├── ResourceLoaderScriptFileLoader.java │ │ ├── TryLookupEntityListenerProvider.java │ │ ├── UnifiedCriteriaPageable.java │ │ ├── event │ │ ├── DomaApplicationListener.java │ │ ├── DomaEvent.java │ │ ├── DomaEventEntityListener.java │ │ ├── DomaEventListenerFactory.java │ │ ├── PostDeleteEvent.java │ │ ├── PostInsertEvent.java │ │ ├── PostUpdateEvent.java │ │ ├── PreDeleteEvent.java │ │ ├── PreInsertEvent.java │ │ ├── PreUpdateEvent.java │ │ ├── annotation │ │ │ ├── HandleDomaEvent.java │ │ │ ├── HandlePostDelete.java │ │ │ ├── HandlePostInsert.java │ │ │ ├── HandlePostUpdate.java │ │ │ ├── HandlePreDelete.java │ │ │ ├── HandlePreInsert.java │ │ │ ├── HandlePreUpdate.java │ │ │ └── package-info.java │ │ └── package-info.java │ │ └── package-info.java │ └── test │ └── java │ └── org │ └── seasar │ └── doma │ └── boot │ ├── DomaPersistenceExceptionTranslatorTest.java │ ├── PageablesTest.java │ ├── ResourceLoaderScriptFileLoaderTest.java │ ├── TryLookupEntityListenerProviderTest.java │ ├── UnifiedCriteriaPageableTest.java │ └── event │ ├── DomaApplicationListenerTest.java │ └── DomaEventEntityListenerTest.java ├── doma-spring-boot-jacoco-aggregate └── pom.xml ├── doma-spring-boot-samples ├── doma-spring-boot-sample-docker-compose │ ├── README.md │ ├── compose.yaml │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── org │ │ │ │ └── seasar │ │ │ │ └── doma │ │ │ │ └── boot │ │ │ │ └── sample │ │ │ │ ├── Application.java │ │ │ │ ├── Message.java │ │ │ │ ├── MessageController.java │ │ │ │ └── MessageDao.java │ │ └── resources │ │ │ ├── META-INF │ │ │ └── org │ │ │ │ └── seasar │ │ │ │ └── doma │ │ │ │ └── boot │ │ │ │ └── sample │ │ │ │ └── MessageDao │ │ │ │ └── selectAll.sql │ │ │ ├── application.properties │ │ │ └── schema.sql │ │ └── test │ │ └── java │ │ └── org │ │ └── seasar │ │ └── doma │ │ └── boot │ │ └── sample │ │ └── ApplicationTest.java ├── doma-spring-boot-sample-entity-listener │ ├── .mvn │ │ └── wrapper │ │ │ ├── maven-wrapper.jar │ │ │ └── maven-wrapper.properties │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── org │ │ │ │ └── seasar │ │ │ │ └── doma │ │ │ │ └── boot │ │ │ │ └── sample │ │ │ │ ├── Application.java │ │ │ │ ├── Message.java │ │ │ │ ├── MessageController.java │ │ │ │ ├── MessageDao.java │ │ │ │ └── MessageListener.java │ │ └── resources │ │ │ ├── META-INF │ │ │ └── org │ │ │ │ └── seasar │ │ │ │ └── doma │ │ │ │ └── boot │ │ │ │ └── sample │ │ │ │ └── MessageDao │ │ │ │ └── selectAll.sql │ │ │ ├── application.properties │ │ │ └── schema.sql │ │ └── test │ │ └── java │ │ └── org │ │ └── seasar │ │ └── doma │ │ └── boot │ │ └── sample │ │ └── ApplicationTest.java ├── doma-spring-boot-sample-event-handler │ ├── .mvn │ │ └── wrapper │ │ │ ├── maven-wrapper.jar │ │ │ └── maven-wrapper.properties │ ├── mvnw │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── org │ │ │ │ └── seasar │ │ │ │ └── doma │ │ │ │ └── boot │ │ │ │ └── sample │ │ │ │ ├── Application.java │ │ │ │ ├── Message.java │ │ │ │ ├── MessageController.java │ │ │ │ ├── MessageDao.java │ │ │ │ └── MessageHandler.java │ │ └── resources │ │ │ ├── META-INF │ │ │ └── org │ │ │ │ └── seasar │ │ │ │ └── doma │ │ │ │ └── boot │ │ │ │ └── sample │ │ │ │ └── MessageDao │ │ │ │ └── selectAll.sql │ │ │ ├── application.properties │ │ │ └── schema.sql │ │ └── test │ │ └── java │ │ └── org │ │ └── seasar │ │ └── doma │ │ └── boot │ │ └── sample │ │ └── ApplicationTest.java ├── doma-spring-boot-sample-simple │ ├── .mvn │ │ └── wrapper │ │ │ ├── maven-wrapper.jar │ │ │ └── maven-wrapper.properties │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── org │ │ │ │ └── seasar │ │ │ │ └── doma │ │ │ │ └── boot │ │ │ │ └── sample │ │ │ │ ├── Application.java │ │ │ │ ├── Message.java │ │ │ │ ├── MessageController.java │ │ │ │ └── MessageDao.java │ │ └── resources │ │ │ ├── META-INF │ │ │ └── org │ │ │ │ └── seasar │ │ │ │ └── doma │ │ │ │ └── boot │ │ │ │ └── sample │ │ │ │ └── MessageDao │ │ │ │ └── selectAll.sql │ │ │ ├── application.properties │ │ │ └── schema.sql │ │ └── test │ │ └── java │ │ └── org │ │ └── seasar │ │ └── doma │ │ └── boot │ │ └── sample │ │ └── ApplicationTest.java ├── doma-spring-boot-sample-testcontainers │ ├── .mvn │ │ └── wrapper │ │ │ ├── MavenWrapperDownloader.java │ │ │ ├── maven-wrapper.jar │ │ │ └── maven-wrapper.properties │ ├── README.md │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── org │ │ │ │ └── seasar │ │ │ │ └── doma │ │ │ │ └── boot │ │ │ │ └── sample │ │ │ │ ├── Application.java │ │ │ │ ├── Message.java │ │ │ │ ├── MessageController.java │ │ │ │ └── MessageDao.java │ │ └── resources │ │ │ ├── META-INF │ │ │ └── org │ │ │ │ └── seasar │ │ │ │ └── doma │ │ │ │ └── boot │ │ │ │ └── sample │ │ │ │ └── MessageDao │ │ │ │ └── selectAll.sql │ │ │ ├── application.properties │ │ │ └── schema.sql │ │ └── test │ │ └── java │ │ └── org │ │ └── seasar │ │ └── doma │ │ └── boot │ │ └── sample │ │ ├── ApplicationTest.java │ │ ├── TestApplication.java │ │ └── TestcontainersConfiguration.java ├── doma-spring-boot-sample-two-datasource │ ├── .mvn │ │ └── wrapper │ │ │ ├── maven-wrapper.jar │ │ │ └── maven-wrapper.properties │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── org │ │ │ │ └── seasar │ │ │ │ └── doma │ │ │ │ └── boot │ │ │ │ └── sample │ │ │ │ ├── Application.java │ │ │ │ ├── annotation │ │ │ │ ├── Secondary.java │ │ │ │ └── SecondaryConfigAutowireable.java │ │ │ │ ├── configuration │ │ │ │ ├── DataSourceConfiguration.java │ │ │ │ ├── DomaConfiguration.java │ │ │ │ └── TransactionManagerConfiguration.java │ │ │ │ ├── dao │ │ │ │ ├── PrimaryDao.java │ │ │ │ └── SecondaryDao.java │ │ │ │ ├── entity │ │ │ │ ├── PrimaryMessage.java │ │ │ │ └── SecondaryMessage.java │ │ │ │ └── service │ │ │ │ └── SampleService.java │ │ └── resources │ │ │ ├── META-INF │ │ │ └── org │ │ │ │ └── seasar │ │ │ │ └── doma │ │ │ │ └── boot │ │ │ │ └── sample │ │ │ │ └── dao │ │ │ │ ├── PrimaryDao │ │ │ │ └── selectById.sql │ │ │ │ └── SecondaryDao │ │ │ │ └── selectById.sql │ │ │ ├── application.properties │ │ │ ├── data.sql │ │ │ ├── schema.sql │ │ │ ├── secondary-data.sql │ │ │ └── secondary-schema.sql │ │ └── test │ │ └── java │ │ └── org │ │ └── seasar │ │ └── doma │ │ └── boot │ │ └── sample │ │ └── ApplicationTest.java ├── doma-spring-boot-sample-unified-criteria │ ├── .mvn │ │ └── wrapper │ │ │ ├── maven-wrapper.jar │ │ │ └── maven-wrapper.properties │ ├── mvnw │ ├── mvnw.cmd │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── org │ │ │ │ └── seasar │ │ │ │ └── doma │ │ │ │ └── boot │ │ │ │ └── sample │ │ │ │ ├── Application.java │ │ │ │ ├── Message.java │ │ │ │ └── MessageController.java │ │ └── resources │ │ │ ├── application.properties │ │ │ └── schema.sql │ │ └── test │ │ └── java │ │ └── org │ │ └── seasar │ │ └── doma │ │ └── boot │ │ └── sample │ │ └── ApplicationTest.java └── pom.xml ├── doma-spring-boot-starter ├── pom.xml └── src │ └── main │ └── resources │ └── META-INF │ └── spring.provides ├── eclipse └── eclipse-code-formatter.xml ├── how-to-release.md ├── mvnw ├── mvnw.cmd ├── pom.xml └── renovate.json /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Java CI with Maven 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | env: 10 | MAVEN_CLI_OPTS: --batch-mode --no-transfer-progress 11 | 12 | jobs: 13 | test: 14 | if: contains(github.event.head_commit.message, '[skip ci]') == false 15 | runs-on: ubuntu-latest 16 | timeout-minutes: 30 17 | 18 | steps: 19 | - uses: actions/checkout@v4 20 | 21 | - name: Set up JDK 17 22 | uses: actions/setup-java@v4 23 | with: 24 | distribution: liberica 25 | java-version: 17 26 | cache: maven 27 | 28 | - name: Grant execute permission for mvnw 29 | run: chmod +x mvnw 30 | 31 | - name: Test with Maven 32 | run: ./mvnw $MAVEN_CLI_OPTS formatter:validate test 33 | 34 | - name: Upload reports 35 | if: failure() 36 | uses: actions/upload-artifact@v4 37 | with: 38 | name: reports 39 | path: ./**/target/surefire-reports 40 | 41 | test-matrix: 42 | if: contains(github.event.head_commit.message, '[skip ci]') == false 43 | runs-on: ubuntu-latest 44 | timeout-minutes: 30 45 | needs: [ test ] 46 | 47 | strategy: 48 | matrix: 49 | # Latest LTS, latest release 50 | java: [ 21, 24 ] 51 | # OSS support versions 52 | # https://spring.io/projects/spring-boot#support 53 | # and milestone version of the next release 54 | spring-boot-version: [ 3.4.4, 3.5.0-M3 ] 55 | 56 | steps: 57 | - uses: actions/checkout@v4 58 | 59 | - name: Set up JDK ${{ matrix.java }} 60 | uses: actions/setup-java@v4 61 | with: 62 | distribution: liberica 63 | java-version: ${{ matrix.java }} 64 | cache: maven 65 | 66 | - name: Grant execute permission for mvnw 67 | run: chmod +x mvnw 68 | 69 | - name: Test with Maven 70 | run: ./mvnw $MAVEN_CLI_OPTS -pl :doma-spring-boot-core,:doma-spring-boot-autoconfigure,:doma-spring-boot-starter test -Dspring-boot.version=${{ matrix.spring-boot-version }} 71 | 72 | - name: Upload reports 73 | if: failure() 74 | uses: actions/upload-artifact@v4 75 | with: 76 | name: reports 77 | path: ./**/target/surefire-reports 78 | 79 | deploy: 80 | if: github.event_name == 'push' && contains(github.event.head_commit.message, '[skip ci]') == false 81 | runs-on: ubuntu-latest 82 | needs: [ test-matrix ] 83 | 84 | steps: 85 | - uses: actions/checkout@v4 86 | 87 | - name: Set up JDK 17 88 | uses: actions/setup-java@v4 89 | with: 90 | distribution: liberica 91 | java-version: 17 92 | cache: maven 93 | 94 | - name: Grant execute permission for mvnw 95 | run: chmod +x mvnw 96 | 97 | - name: Release Maven package 98 | uses: samuelmeuli/action-maven-publish@v1 99 | with: 100 | gpg_private_key: ${{ secrets.SIGNING_KEY }} 101 | gpg_passphrase: ${{ secrets.SIGNING_PASSWORD }} 102 | nexus_username: ${{ secrets.OSSRH_USERNAME }} 103 | nexus_password: ${{ secrets.OSSRH_PASSWORD }} 104 | 105 | - name: Upload reports 106 | if: failure() 107 | uses: actions/upload-artifact@v4 108 | with: 109 | name: reports 110 | path: ./**/target/surefire-reports 111 | -------------------------------------------------------------------------------- /.github/workflows/close-inactive-issues.yml: -------------------------------------------------------------------------------- 1 | name: Close inactive issues 2 | on: 3 | schedule: 4 | - cron: "30 1 * * *" 5 | 6 | jobs: 7 | close-issues: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/stale@v9 11 | with: 12 | days-before-issue-stale: 60 13 | days-before-issue-close: 30 14 | stale-issue-label: "stale" 15 | stale-issue-message: "This issue is stale because it has been open for 60 days with no activity." 16 | close-issue-message: "This issue was closed because it has been inactive for 30 days since being marked as stale." 17 | days-before-pr-stale: 60 18 | days-before-pr-close: 30 19 | stale-pr-message: "This pull request is stale because it has been open for 60 days with no activity." 20 | close-pr-message: "This pull request was closed because it has been inactive for 30 days since being marked as stale." 21 | repo-token: ${{ secrets.GITHUB_TOKEN }} 22 | 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | target 3 | *.iml 4 | *~ 5 | .*~ 6 | *.versionsBackup 7 | .classpath 8 | .project 9 | .settings 10 | .factorypath 11 | .apt_generated 12 | .vscode/ 13 | HELP.md 14 | -------------------------------------------------------------------------------- /.mvn/wrapper/MavenWrapperDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-present 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 | * http://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 | import java.net.*; 17 | import java.io.*; 18 | import java.nio.channels.*; 19 | import java.util.Properties; 20 | 21 | public class MavenWrapperDownloader { 22 | 23 | private static final String WRAPPER_VERSION = "0.5.6"; 24 | /** 25 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. 26 | */ 27 | private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" 28 | + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; 29 | 30 | /** 31 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to 32 | * use instead of the default one. 33 | */ 34 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = 35 | ".mvn/wrapper/maven-wrapper.properties"; 36 | 37 | /** 38 | * Path where the maven-wrapper.jar will be saved to. 39 | */ 40 | private static final String MAVEN_WRAPPER_JAR_PATH = 41 | ".mvn/wrapper/maven-wrapper.jar"; 42 | 43 | /** 44 | * Name of the property which should be used to override the default download url for the wrapper. 45 | */ 46 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; 47 | 48 | public static void main(String args[]) { 49 | System.out.println("- Downloader started"); 50 | File baseDirectory = new File(args[0]); 51 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); 52 | 53 | // If the maven-wrapper.properties exists, read it and check if it contains a custom 54 | // wrapperUrl parameter. 55 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); 56 | String url = DEFAULT_DOWNLOAD_URL; 57 | if(mavenWrapperPropertyFile.exists()) { 58 | FileInputStream mavenWrapperPropertyFileInputStream = null; 59 | try { 60 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); 61 | Properties mavenWrapperProperties = new Properties(); 62 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); 63 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); 64 | } catch (IOException e) { 65 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); 66 | } finally { 67 | try { 68 | if(mavenWrapperPropertyFileInputStream != null) { 69 | mavenWrapperPropertyFileInputStream.close(); 70 | } 71 | } catch (IOException e) { 72 | // Ignore ... 73 | } 74 | } 75 | } 76 | System.out.println("- Downloading from: " + url); 77 | 78 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); 79 | if(!outputFile.getParentFile().exists()) { 80 | if(!outputFile.getParentFile().mkdirs()) { 81 | System.out.println( 82 | "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); 83 | } 84 | } 85 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); 86 | try { 87 | downloadFileFromURL(url, outputFile); 88 | System.out.println("Done"); 89 | System.exit(0); 90 | } catch (Throwable e) { 91 | System.out.println("- Error downloading"); 92 | e.printStackTrace(); 93 | System.exit(1); 94 | } 95 | } 96 | 97 | private static void downloadFileFromURL(String urlString, File destination) throws Exception { 98 | if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { 99 | String username = System.getenv("MVNW_USERNAME"); 100 | char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); 101 | Authenticator.setDefault(new Authenticator() { 102 | @Override 103 | protected PasswordAuthentication getPasswordAuthentication() { 104 | return new PasswordAuthentication(username, password); 105 | } 106 | }); 107 | } 108 | URL website = new URL(urlString); 109 | ReadableByteChannel rbc; 110 | rbc = Channels.newChannel(website.openStream()); 111 | FileOutputStream fos = new FileOutputStream(destination); 112 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 113 | fos.close(); 114 | rbc.close(); 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/domaframework/doma-spring-boot/3d75478c299a8b4b55579f23245b2c387b3631ce/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.10/apache-maven-3.9.10-bin.zip 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # doma-spring-boot 2 | 3 | Spring Boot Support for [Doma](https://github.com/domaframework/doma) 4 | 5 | [![Java CI with Maven](https://github.com/domaframework/doma-spring-boot/workflows/Java%20CI%20with%20Maven/badge.svg)](https://github.com/domaframework/doma-spring-boot/actions?query=workflow%3A%22Java+CI+with+Maven%22) 6 | 7 | ## Document 8 | 9 | [GitHub Wiki](https://github.com/domaframework/doma-spring-boot/wiki) 10 | 11 | ## Issue Tracking 12 | 13 | [GitHub Issues](https://github.com/domaframework/doma-spring-boot/issues) 14 | 15 | ## Maven dependency 16 | 17 | ``` xml 18 | 19 | org.seasar.doma.boot 20 | doma-spring-boot-starter 21 | 2.4.0 22 | 23 | 24 | org.seasar.doma 25 | doma-processor 26 | 3.6.0 27 | true 28 | 29 | ``` 30 | 31 | Add the following repository to use snapshots. 32 | 33 | ``` xml 34 | 35 | sonatype-snapshots 36 | Sonatype Snapshots 37 | https://oss.sonatype.org/content/repositories/snapshots 38 | 39 | true 40 | 41 | 42 | ``` 43 | 44 | ## License 45 | 46 | Licensed under the Apache License, Version 2.0. 47 | -------------------------------------------------------------------------------- /doma-spring-boot-autoconfigure/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | doma-spring-boot-autoconfigure 7 | jar 8 | 9 | doma-spring-boot-autoconfigure 10 | Spring Boot AutoConfigure project for Doma 11 | 12 | 13 | org.seasar.doma.boot 14 | doma-spring-boot 15 | 2.5.0-SNAPSHOT 16 | ../pom.xml 17 | 18 | 19 | 20 | 21 | org.seasar.doma.boot 22 | doma-spring-boot-core 23 | ${project.version} 24 | 25 | 26 | org.seasar.doma 27 | doma-slf4j 28 | ${doma.version} 29 | 30 | 31 | org.springframework 32 | spring-jdbc 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-autoconfigure 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-configuration-processor 41 | true 42 | 43 | 44 | org.springframework.boot 45 | spring-boot-starter-test 46 | test 47 | 48 | 49 | org.junit.jupiter 50 | junit-jupiter 51 | test 52 | 53 | 54 | com.h2database 55 | h2 56 | test 57 | 58 | 59 | org.postgresql 60 | postgresql 61 | test 62 | 63 | 64 | com.zaxxer 65 | HikariCP 66 | test 67 | 68 | 69 | 70 | 71 | 72 | 73 | org.apache.maven.plugins 74 | maven-jar-plugin 75 | 76 | 77 | 78 | doma.spring.boot.autoconfigure 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /doma-spring-boot-autoconfigure/src/main/java/org/seasar/doma/boot/autoconfigure/DomaConfig.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.autoconfigure; 2 | 3 | import javax.sql.DataSource; 4 | 5 | import org.seasar.doma.jdbc.*; 6 | import org.seasar.doma.jdbc.dialect.Dialect; 7 | import org.seasar.doma.jdbc.statistic.StatisticManager; 8 | 9 | /** 10 | * {@link Config} implementation used in doma-spring-boot. 11 | * 12 | * @author Toshiaki Maki 13 | */ 14 | public class DomaConfig implements Config { 15 | 16 | private final DataSource dataSource; 17 | private final Dialect dialect; 18 | private final JdbcLogger jdbcLogger; 19 | private final SqlFileRepository sqlFileRepository; 20 | private final RequiresNewController requiresNewController; 21 | private final ClassHelper classHelper; 22 | private final CommandImplementors commandImplementors; 23 | private final QueryImplementors queryImplementors; 24 | private final UnknownColumnHandler unknownColumnHandler; 25 | private final Naming naming; 26 | private final MapKeyNaming mapKeyNaming; 27 | private final Commenter commenter; 28 | private final EntityListenerProvider entityListenerProvider; 29 | private final DomaProperties domaProperties; 30 | private final DuplicateColumnHandler duplicateColumnHandler; 31 | private final ScriptFileLoader scriptFileLoader; 32 | private final SqlBuilderSettings sqlBuilderSettings; 33 | private final StatisticManager statisticManager; 34 | 35 | public DomaConfig(DomaConfigBuilder builder, DomaProperties domaProperties) { 36 | this.dataSource = builder.dataSource(); 37 | this.dialect = builder.dialect(); 38 | this.jdbcLogger = builder.jdbcLogger(); 39 | this.sqlFileRepository = builder.sqlFileRepository(); 40 | this.requiresNewController = builder.requiresNewController(); 41 | this.classHelper = builder.classHelper(); 42 | this.commandImplementors = builder.commandImplementors(); 43 | this.queryImplementors = builder.queryImplementors(); 44 | this.unknownColumnHandler = builder.unknownColumnHandler(); 45 | this.naming = builder.naming(); 46 | this.mapKeyNaming = builder.mapKeyNaming(); 47 | this.commenter = builder.commenter(); 48 | this.entityListenerProvider = builder.entityListenerProvider(); 49 | this.duplicateColumnHandler = builder.duplicateColumnHandler(); 50 | this.scriptFileLoader = builder.scriptFileLoader(); 51 | this.sqlBuilderSettings = builder.sqlBuilderSettings(); 52 | this.statisticManager = builder.statisticManager(); 53 | this.domaProperties = domaProperties; 54 | } 55 | 56 | @Override 57 | public DataSource getDataSource() { 58 | return this.dataSource; 59 | } 60 | 61 | @Override 62 | public Dialect getDialect() { 63 | return this.dialect; 64 | } 65 | 66 | @Override 67 | public String getDataSourceName() { 68 | return this.domaProperties.getDataSourceName(); 69 | } 70 | 71 | @Override 72 | public SqlFileRepository getSqlFileRepository() { 73 | return this.sqlFileRepository; 74 | } 75 | 76 | @Override 77 | public JdbcLogger getJdbcLogger() { 78 | return this.jdbcLogger; 79 | } 80 | 81 | @Override 82 | public RequiresNewController getRequiresNewController() { 83 | return this.requiresNewController; 84 | } 85 | 86 | @Override 87 | public ClassHelper getClassHelper() { 88 | return this.classHelper; 89 | } 90 | 91 | @Override 92 | public CommandImplementors getCommandImplementors() { 93 | return this.commandImplementors; 94 | } 95 | 96 | @Override 97 | public QueryImplementors getQueryImplementors() { 98 | return this.queryImplementors; 99 | } 100 | 101 | @Override 102 | public SqlLogType getExceptionSqlLogType() { 103 | return this.domaProperties.getExceptionSqlLogType(); 104 | } 105 | 106 | @Override 107 | public UnknownColumnHandler getUnknownColumnHandler() { 108 | return this.unknownColumnHandler; 109 | } 110 | 111 | @Override 112 | public Naming getNaming() { 113 | return this.naming; 114 | } 115 | 116 | @Override 117 | public MapKeyNaming getMapKeyNaming() { 118 | return this.mapKeyNaming; 119 | } 120 | 121 | @Override 122 | public Commenter getCommenter() { 123 | return this.commenter; 124 | } 125 | 126 | @Override 127 | public int getMaxRows() { 128 | return this.domaProperties.getMaxRows(); 129 | } 130 | 131 | @Override 132 | public int getFetchSize() { 133 | return this.domaProperties.getFetchSize(); 134 | } 135 | 136 | @Override 137 | public int getQueryTimeout() { 138 | return this.domaProperties.getQueryTimeout(); 139 | } 140 | 141 | @Override 142 | public int getBatchSize() { 143 | return this.domaProperties.getBatchSize(); 144 | } 145 | 146 | @Override 147 | public EntityListenerProvider getEntityListenerProvider() { 148 | return this.entityListenerProvider; 149 | } 150 | 151 | @Override 152 | public DuplicateColumnHandler getDuplicateColumnHandler() { 153 | return this.duplicateColumnHandler; 154 | } 155 | 156 | @Override 157 | public ScriptFileLoader getScriptFileLoader() { 158 | return this.scriptFileLoader; 159 | } 160 | 161 | @Override 162 | public SqlBuilderSettings getSqlBuilderSettings() { 163 | return this.sqlBuilderSettings; 164 | } 165 | 166 | @Override 167 | public StatisticManager getStatisticManager() { 168 | return this.statisticManager; 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /doma-spring-boot-autoconfigure/src/main/java/org/seasar/doma/boot/autoconfigure/DomaConfigBuilder.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.autoconfigure; 2 | 3 | import java.util.Objects; 4 | 5 | import javax.sql.DataSource; 6 | 7 | import org.seasar.doma.jdbc.*; 8 | import org.seasar.doma.jdbc.dialect.Dialect; 9 | import org.seasar.doma.jdbc.statistic.StatisticManager; 10 | import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy; 11 | 12 | /** 13 | * Builder to create {@link DomaConfig}. 14 | * 15 | * @author Toshiaki Maki 16 | */ 17 | public class DomaConfigBuilder { 18 | private DomaProperties domaProperties; 19 | private DataSource dataSource; 20 | /** 21 | * Default value is set in {@link DomaProperties} 22 | */ 23 | private Dialect dialect; 24 | /** 25 | * Default value is set in {@link DomaProperties} 26 | */ 27 | private JdbcLogger jdbcLogger; 28 | /** 29 | * Default value is set in {@link DomaProperties} 30 | */ 31 | private SqlFileRepository sqlFileRepository; 32 | private RequiresNewController requiresNewController = ConfigSupport.defaultRequiresNewController; 33 | private ClassHelper classHelper = ConfigSupport.defaultClassHelper; 34 | private CommandImplementors commandImplementors = ConfigSupport.defaultCommandImplementors; 35 | private QueryImplementors queryImplementors = ConfigSupport.defaultQueryImplementors; 36 | private UnknownColumnHandler unknownColumnHandler = ConfigSupport.defaultUnknownColumnHandler; 37 | /** 38 | * Default value is set in {@link DomaProperties} 39 | */ 40 | private Naming naming; 41 | private MapKeyNaming mapKeyNaming = ConfigSupport.defaultMapKeyNaming; 42 | private Commenter commenter = ConfigSupport.defaultCommenter; 43 | private EntityListenerProvider entityListenerProvider; 44 | private DuplicateColumnHandler duplicateColumnHandler; 45 | private ScriptFileLoader scriptFileLoader; 46 | private SqlBuilderSettings sqlBuilderSettings; 47 | private StatisticManager statisticManager; 48 | 49 | public DomaConfigBuilder(DomaProperties domaProperties) { 50 | this.domaProperties = Objects.requireNonNull(domaProperties); 51 | } 52 | 53 | public DataSource dataSource() { 54 | return dataSource; 55 | } 56 | 57 | /** 58 | * Set dataSource
59 | *

60 | * Note that the given dataSource is wrapped by 61 | * {@link TransactionAwareDataSourceProxy}. 62 | * 63 | * @param dataSource dataSource to use 64 | * @return chained builder 65 | */ 66 | public DomaConfigBuilder dataSource(DataSource dataSource) { 67 | this.dataSource = new TransactionAwareDataSourceProxy(dataSource); 68 | return this; 69 | } 70 | 71 | public Dialect dialect() { 72 | return dialect; 73 | } 74 | 75 | public DomaConfigBuilder dialect(Dialect dialect) { 76 | this.dialect = dialect; 77 | return this; 78 | } 79 | 80 | public JdbcLogger jdbcLogger() { 81 | return jdbcLogger; 82 | } 83 | 84 | public DomaConfigBuilder jdbcLogger(JdbcLogger jdbcLogger) { 85 | this.jdbcLogger = jdbcLogger; 86 | return this; 87 | } 88 | 89 | public SqlFileRepository sqlFileRepository() { 90 | return sqlFileRepository; 91 | } 92 | 93 | public DomaConfigBuilder sqlFileRepository(SqlFileRepository sqlFileRepository) { 94 | this.sqlFileRepository = sqlFileRepository; 95 | return this; 96 | } 97 | 98 | public RequiresNewController requiresNewController() { 99 | return requiresNewController; 100 | } 101 | 102 | public DomaConfigBuilder requiresNewController( 103 | RequiresNewController requiresNewController) { 104 | this.requiresNewController = requiresNewController; 105 | return this; 106 | } 107 | 108 | public ClassHelper classHelper() { 109 | return classHelper; 110 | } 111 | 112 | public DomaConfigBuilder classHelper(ClassHelper classHelper) { 113 | this.classHelper = classHelper; 114 | return this; 115 | } 116 | 117 | public CommandImplementors commandImplementors() { 118 | return commandImplementors; 119 | } 120 | 121 | public DomaConfigBuilder commandImplementors(CommandImplementors commandImplementors) { 122 | this.commandImplementors = commandImplementors; 123 | return this; 124 | } 125 | 126 | public QueryImplementors queryImplementors() { 127 | return queryImplementors; 128 | } 129 | 130 | public DomaConfigBuilder queryImplementors(QueryImplementors queryImplementors) { 131 | this.queryImplementors = queryImplementors; 132 | return this; 133 | } 134 | 135 | public UnknownColumnHandler unknownColumnHandler() { 136 | return unknownColumnHandler; 137 | } 138 | 139 | public DomaConfigBuilder unknownColumnHandler( 140 | UnknownColumnHandler unknownColumnHandler) { 141 | this.unknownColumnHandler = unknownColumnHandler; 142 | return this; 143 | } 144 | 145 | public Naming naming() { 146 | return naming; 147 | } 148 | 149 | public DomaConfigBuilder naming(Naming naming) { 150 | this.naming = naming; 151 | return this; 152 | } 153 | 154 | public MapKeyNaming mapKeyNaming() { 155 | return mapKeyNaming; 156 | } 157 | 158 | public DomaConfigBuilder mapKeyNaming(MapKeyNaming mapKeyNaming) { 159 | this.mapKeyNaming = mapKeyNaming; 160 | return this; 161 | } 162 | 163 | public Commenter commenter() { 164 | return commenter; 165 | } 166 | 167 | public DomaConfigBuilder commenter(Commenter commenter) { 168 | this.commenter = commenter; 169 | return this; 170 | } 171 | 172 | public EntityListenerProvider entityListenerProvider() { 173 | return entityListenerProvider; 174 | } 175 | 176 | public DomaConfigBuilder entityListenerProvider( 177 | EntityListenerProvider entityListenerProvider) { 178 | this.entityListenerProvider = entityListenerProvider; 179 | return this; 180 | } 181 | 182 | public DuplicateColumnHandler duplicateColumnHandler() { 183 | return duplicateColumnHandler; 184 | } 185 | 186 | public DomaConfigBuilder duplicateColumnHandler(DuplicateColumnHandler duplicateColumnHandler) { 187 | this.duplicateColumnHandler = duplicateColumnHandler; 188 | return this; 189 | } 190 | 191 | public ScriptFileLoader scriptFileLoader() { 192 | return scriptFileLoader; 193 | } 194 | 195 | public DomaConfigBuilder scriptFileLoader(ScriptFileLoader scriptFileLoader) { 196 | this.scriptFileLoader = scriptFileLoader; 197 | return this; 198 | } 199 | 200 | public SqlBuilderSettings sqlBuilderSettings() { 201 | return sqlBuilderSettings; 202 | } 203 | 204 | public DomaConfigBuilder sqlBuilderSettings(SqlBuilderSettings sqlBuilderSettings) { 205 | this.sqlBuilderSettings = sqlBuilderSettings; 206 | return this; 207 | } 208 | 209 | public StatisticManager statisticManager() { 210 | return statisticManager; 211 | } 212 | 213 | public DomaConfigBuilder statisticManager(StatisticManager statisticManager) { 214 | this.statisticManager = statisticManager; 215 | return this; 216 | } 217 | 218 | public DomaConfig build() { 219 | return new DomaConfig(this, domaProperties); 220 | } 221 | } 222 | -------------------------------------------------------------------------------- /doma-spring-boot-autoconfigure/src/main/java/org/seasar/doma/boot/autoconfigure/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Auto-configuration for Doma. 3 | */ 4 | package org.seasar.doma.boot.autoconfigure; 5 | -------------------------------------------------------------------------------- /doma-spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | # Auto Configure 2 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 3 | org.seasar.doma.boot.autoconfigure.DomaAutoConfiguration -------------------------------------------------------------------------------- /doma-spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | org.seasar.doma.boot.autoconfigure.DomaAutoConfiguration 2 | 3 | -------------------------------------------------------------------------------- /doma-spring-boot-core/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | doma-spring-boot-core 7 | jar 8 | 9 | doma-spring-boot-core 10 | Spring Boot Core project for Doma 11 | 12 | 13 | org.seasar.doma.boot 14 | doma-spring-boot 15 | 2.5.0-SNAPSHOT 16 | ../pom.xml 17 | 18 | 19 | 20 | 21 | org.seasar.doma 22 | doma-core 23 | ${doma.version} 24 | 25 | 26 | org.springframework 27 | spring-context 28 | 29 | 30 | org.springframework 31 | spring-jdbc 32 | 33 | 34 | org.springframework.data 35 | spring-data-commons 36 | 37 | 38 | org.junit.jupiter 39 | junit-jupiter 40 | test 41 | 42 | 43 | org.assertj 44 | assertj-core 45 | test 46 | 47 | 48 | org.mockito 49 | mockito-core 50 | test 51 | 52 | 53 | com.h2database 54 | h2 55 | test 56 | 57 | 58 | 59 | 60 | 61 | 62 | org.apache.maven.plugins 63 | maven-jar-plugin 64 | 65 | 66 | 67 | doma.spring.boot.core 68 | 69 | 70 | 71 | 72 | 73 | org.apache.maven.plugins 74 | maven-compiler-plugin 75 | 76 | 77 | 78 | org.seasar.doma 79 | doma-processor 80 | ${doma.version} 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /doma-spring-boot-core/src/main/java/org/seasar/doma/boot/ConfigAutowireable.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot; 2 | 3 | import org.seasar.doma.AnnotateWith; 4 | import org.seasar.doma.Annotation; 5 | import org.seasar.doma.AnnotationTarget; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Repository; 8 | 9 | /** 10 | * Annotate {@link Repository} on the generated Dao class and {@link Autowired} on the 11 | * constructor. 12 | * @author Toshiaki Maki 13 | */ 14 | @AnnotateWith(annotations = { 15 | @Annotation(target = AnnotationTarget.CLASS, type = Repository.class), 16 | @Annotation(target = AnnotationTarget.CONSTRUCTOR, type = Autowired.class) }) 17 | public @interface ConfigAutowireable { 18 | } 19 | -------------------------------------------------------------------------------- /doma-spring-boot-core/src/main/java/org/seasar/doma/boot/DomaPersistenceExceptionTranslator.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot; 2 | 3 | import java.sql.SQLException; 4 | 5 | import org.seasar.doma.jdbc.JdbcException; 6 | import org.seasar.doma.jdbc.NoResultException; 7 | import org.seasar.doma.jdbc.NonSingleColumnException; 8 | import org.seasar.doma.jdbc.NonUniqueResultException; 9 | import org.seasar.doma.jdbc.OptimisticLockException; 10 | import org.seasar.doma.jdbc.ResultMappingException; 11 | import org.seasar.doma.jdbc.SqlExecutionException; 12 | import org.seasar.doma.jdbc.UniqueConstraintException; 13 | import org.seasar.doma.jdbc.UnknownColumnException; 14 | import org.springframework.dao.DataAccessException; 15 | import org.springframework.dao.DuplicateKeyException; 16 | import org.springframework.dao.EmptyResultDataAccessException; 17 | import org.springframework.dao.IncorrectResultSizeDataAccessException; 18 | import org.springframework.dao.OptimisticLockingFailureException; 19 | import org.springframework.dao.TypeMismatchDataAccessException; 20 | import org.springframework.dao.UncategorizedDataAccessException; 21 | import org.springframework.dao.support.PersistenceExceptionTranslator; 22 | import org.springframework.jdbc.UncategorizedSQLException; 23 | import org.springframework.jdbc.support.SQLExceptionTranslator; 24 | 25 | /** 26 | * Converts Doma's {@link JdbcException} into Spring's {@link DataAccessException}. 27 | * @author Toshiaki Maki 28 | * @author Kazuki Shimizu 29 | */ 30 | public class DomaPersistenceExceptionTranslator implements PersistenceExceptionTranslator { 31 | 32 | private final SQLExceptionTranslator translator; 33 | 34 | public DomaPersistenceExceptionTranslator( 35 | SQLExceptionTranslator sqlExceptionTranslator) { 36 | this.translator = sqlExceptionTranslator; 37 | } 38 | 39 | @Override 40 | public DataAccessException translateExceptionIfPossible(RuntimeException ex) { 41 | if (!(ex instanceof JdbcException)) { 42 | // Fallback to other translators if not JdbcException 43 | return null; 44 | } 45 | 46 | if (ex instanceof OptimisticLockException) { 47 | return new OptimisticLockingFailureException(ex.getMessage(), ex); 48 | } else if (ex instanceof UniqueConstraintException) { 49 | return new DuplicateKeyException(ex.getMessage(), ex); 50 | } else if (ex instanceof NonUniqueResultException 51 | || ex instanceof NonSingleColumnException) { 52 | return new IncorrectResultSizeDataAccessException(ex.getMessage(), 1, ex); 53 | } else if (ex instanceof NoResultException) { 54 | return new EmptyResultDataAccessException(ex.getMessage(), 1, ex); 55 | } else if (ex instanceof UnknownColumnException 56 | || ex instanceof ResultMappingException) { 57 | return new TypeMismatchDataAccessException(ex.getMessage(), ex); 58 | } 59 | 60 | if (ex.getCause() instanceof SQLException) { 61 | SQLException e = (SQLException) ex.getCause(); 62 | String sql = null; 63 | if (ex instanceof SqlExecutionException) { 64 | sql = ((SqlExecutionException) ex).getRawSql(); 65 | } 66 | DataAccessException dae = translator.translate(ex.getMessage(), sql, e); 67 | return (dae != null ? dae : new UncategorizedSQLException(ex.getMessage(), sql, e)); 68 | } 69 | 70 | return new UncategorizedDataAccessException(ex.getMessage(), ex) { 71 | }; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /doma-spring-boot-core/src/main/java/org/seasar/doma/boot/DomaSpringBootSqlBuilderSettings.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot; 2 | 3 | import java.util.function.Predicate; 4 | 5 | import org.seasar.doma.jdbc.SqlBuilderSettings; 6 | 7 | public class DomaSpringBootSqlBuilderSettings implements SqlBuilderSettings { 8 | 9 | private final Predicate shouldRemoveBlockComment; 10 | private final Predicate shouldRemoveLineComment; 11 | private final boolean shouldRemoveBlankLines; 12 | private final boolean shouldRequireInListPadding; 13 | 14 | public DomaSpringBootSqlBuilderSettings(Predicate shouldRemoveBlockComment, 15 | Predicate shouldRemoveLineComment, boolean shouldRemoveBlankLines, 16 | boolean shouldRequireInListPadding) { 17 | this.shouldRemoveBlockComment = shouldRemoveBlockComment; 18 | this.shouldRemoveLineComment = shouldRemoveLineComment; 19 | this.shouldRemoveBlankLines = shouldRemoveBlankLines; 20 | this.shouldRequireInListPadding = shouldRequireInListPadding; 21 | } 22 | 23 | @Override 24 | public boolean shouldRemoveBlockComment(String comment) { 25 | return shouldRemoveBlockComment.test(comment); 26 | } 27 | 28 | @Override 29 | public boolean shouldRemoveLineComment(String comment) { 30 | return shouldRemoveLineComment.test(comment); 31 | } 32 | 33 | @Override 34 | public boolean shouldRemoveBlankLines() { 35 | return shouldRemoveBlankLines; 36 | } 37 | 38 | @Override 39 | public boolean shouldRequireInListPadding() { 40 | return shouldRequireInListPadding; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /doma-spring-boot-core/src/main/java/org/seasar/doma/boot/Pageables.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot; 2 | 3 | import org.seasar.doma.jdbc.SelectOptions; 4 | import org.springframework.data.domain.Pageable; 5 | 6 | /** 7 | * Converts Utilities for {@link Pageable} to be used with Doma. 8 | * 9 | * @author Toshiaki Maki 10 | */ 11 | public final class Pageables { 12 | /** 13 | * Converts {@link Pageable} to {@link SelectOptions} 14 | * 15 | * @param pageable {@link Pageable} object to convert 16 | * @return {@link SelectOptions} object corresponds to the given {@link Pageable} 17 | * object. 18 | */ 19 | public static SelectOptions toSelectOptions(Pageable pageable) { 20 | final int offset = pageable.getPageNumber() * pageable.getPageSize(); 21 | final int limit = pageable.getPageSize(); 22 | return SelectOptions.get().offset(offset).limit(limit); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /doma-spring-boot-core/src/main/java/org/seasar/doma/boot/PropertyMetamodelResolver.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot; 2 | 3 | import java.util.Optional; 4 | 5 | import org.seasar.doma.jdbc.criteria.metamodel.PropertyMetamodel; 6 | 7 | /** 8 | * A resolver that maps property names to {@link PropertyMetamodel} 9 | */ 10 | @FunctionalInterface 11 | public interface PropertyMetamodelResolver { 12 | /** 13 | * Resolves the specified property name into a {@link PropertyMetamodel}. 14 | * 15 | * @param propertyName the name of the property to resolve 16 | * @return an {@link Optional} containing the resolved {@link PropertyMetamodel} 17 | * if found, 18 | * or an empty {@link Optional} if the property name cannot be resolved 19 | */ 20 | Optional> resolve(String propertyName); 21 | } 22 | -------------------------------------------------------------------------------- /doma-spring-boot-core/src/main/java/org/seasar/doma/boot/ResourceLoaderScriptFileLoader.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot; 2 | 3 | import java.io.IOException; 4 | import java.io.UncheckedIOException; 5 | import java.net.URL; 6 | 7 | import org.seasar.doma.jdbc.ScriptFileLoader; 8 | import org.springframework.core.io.ResourceLoader; 9 | 10 | public class ResourceLoaderScriptFileLoader implements ScriptFileLoader { 11 | 12 | private final ResourceLoader resourceLoader; 13 | 14 | public ResourceLoaderScriptFileLoader(ResourceLoader resourceLoader) { 15 | this.resourceLoader = resourceLoader; 16 | } 17 | 18 | @Override 19 | public URL loadAsURL(String path) { 20 | try { 21 | var resource = resourceLoader.getResource(ResourceLoader.CLASSPATH_URL_PREFIX + path); 22 | if (resource.exists()) { 23 | return resource.getURL(); 24 | } 25 | resource = resourceLoader.getResource(ResourceLoader.CLASSPATH_URL_PREFIX + "/" + path); 26 | if (resource.exists()) { 27 | return resource.getURL(); 28 | } 29 | return null; 30 | } catch (IOException e) { 31 | throw new UncheckedIOException(e); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /doma-spring-boot-core/src/main/java/org/seasar/doma/boot/TryLookupEntityListenerProvider.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot; 2 | 3 | import java.util.Map; 4 | import java.util.function.Supplier; 5 | 6 | import org.seasar.doma.jdbc.EntityListenerProvider; 7 | import org.seasar.doma.jdbc.entity.EntityListener; 8 | import org.springframework.beans.BeansException; 9 | import org.springframework.context.ApplicationContext; 10 | import org.springframework.context.ApplicationContextAware; 11 | 12 | /** 13 | * {@link EntityListenerProvider} implementation that {@link EntityListener} managed by 14 | * Spring Framework, or else created by Doma. 15 | * 16 | * @author backpaper0 17 | * 18 | */ 19 | public class TryLookupEntityListenerProvider implements EntityListenerProvider, 20 | ApplicationContextAware { 21 | 22 | private ApplicationContext context; 23 | 24 | @Override 25 | public > LISTENER get( 26 | Class listenerClass, Supplier listenerSupplier) { 27 | Map beans = context.getBeansOfType(listenerClass); 28 | if (beans.size() > 1) { 29 | throw new IllegalStateException("Bean type of " + listenerClass 30 | + " bean must be unique!"); 31 | } 32 | return beans.values().stream().findAny().orElseGet(listenerSupplier); 33 | } 34 | 35 | @Override 36 | public void setApplicationContext(ApplicationContext applicationContext) 37 | throws BeansException { 38 | this.context = applicationContext; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /doma-spring-boot-core/src/main/java/org/seasar/doma/boot/event/DomaApplicationListener.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.event; 2 | 3 | import java.lang.annotation.Annotation; 4 | import java.lang.reflect.Method; 5 | import java.lang.reflect.ParameterizedType; 6 | import java.lang.reflect.Type; 7 | import java.util.Collections; 8 | import java.util.IdentityHashMap; 9 | import java.util.Objects; 10 | import java.util.Set; 11 | 12 | import org.seasar.doma.Entity; 13 | import org.seasar.doma.boot.event.annotation.HandleDomaEvent; 14 | import org.springframework.beans.factory.BeanFactory; 15 | import org.springframework.context.ApplicationListener; 16 | import org.springframework.core.annotation.AnnotationUtils; 17 | import org.springframework.core.annotation.MergedAnnotation; 18 | import org.springframework.core.annotation.MergedAnnotations; 19 | import org.springframework.util.ReflectionUtils; 20 | 21 | public class DomaApplicationListener implements ApplicationListener> { 22 | 23 | private final Set> contextClasses; 24 | private final String beanName; 25 | private final Method method; 26 | private final BeanFactory beanFactory; 27 | 28 | public DomaApplicationListener(String beanName, Method method, BeanFactory beanFactory) { 29 | 30 | int parameterCount = method.getParameterCount(); 31 | if (parameterCount < 1) { 32 | throw new IllegalArgumentException("Must receive an entity"); 33 | } else if (parameterCount > 2) { 34 | throw new IllegalArgumentException("Too many parameters"); 35 | } 36 | 37 | Class entityClass = method.getParameterTypes()[0]; 38 | if (entityClass.isAnnotationPresent(Entity.class) == false) { 39 | throw new IllegalArgumentException("First parameter must be entity class"); 40 | } 41 | 42 | Set> contextClasses = Collections.newSetFromMap(new IdentityHashMap<>()); 43 | MergedAnnotations annotations = MergedAnnotations.from(method); 44 | for (MergedAnnotation annotation : annotations) { 45 | HandleDomaEvent handleDomaEvent = AnnotationUtils.findAnnotation( 46 | annotation.getType(), HandleDomaEvent.class); 47 | if (handleDomaEvent != null) { 48 | contextClasses.add(handleDomaEvent.contextClass()); 49 | } 50 | } 51 | 52 | if (parameterCount == 2) { 53 | if (contextClasses.size() > 1) { 54 | throw new IllegalArgumentException( 55 | "To annotate with multi annotations must be only entity parameter"); 56 | } 57 | 58 | Class contextClass = method.getParameterTypes()[1]; 59 | if (contextClass != contextClasses.iterator().next()) { 60 | throw new IllegalArgumentException( 61 | "Mismatch between annotation and event context"); 62 | } 63 | Type t = method.getGenericParameterTypes()[1]; 64 | if (t instanceof ParameterizedType) { 65 | Type typeArg = ((ParameterizedType) t).getActualTypeArguments()[0]; 66 | if (typeArg != entityClass) { 67 | throw new IllegalArgumentException( 68 | "Mismatch between entity class and variable bound to event context"); 69 | } 70 | } 71 | } 72 | 73 | ReflectionUtils.makeAccessible(method); 74 | 75 | this.contextClasses = Objects.requireNonNull(contextClasses); 76 | this.beanName = Objects.requireNonNull(beanName); 77 | this.method = Objects.requireNonNull(method); 78 | this.beanFactory = Objects.requireNonNull(beanFactory); 79 | } 80 | 81 | @Override 82 | public void onApplicationEvent(DomaEvent event) { 83 | Object entity = event.getSource(); 84 | Object context = event.getContext(); 85 | if (shouldHandle(context.getClass()) 86 | && method.getParameterTypes()[0].isAssignableFrom(entity.getClass())) { 87 | Object[] args; 88 | if (method.getParameterCount() == 1) { 89 | args = new Object[] { entity }; 90 | } else { 91 | args = new Object[] { entity, context }; 92 | } 93 | Object target = beanFactory.getBean(beanName); 94 | ReflectionUtils.invokeMethod(method, target, args); 95 | } 96 | } 97 | 98 | private boolean shouldHandle(Class clazz) { 99 | for (Class contextClasse : contextClasses) { 100 | if (contextClasse.isAssignableFrom(clazz)) { 101 | return true; 102 | } 103 | } 104 | return false; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /doma-spring-boot-core/src/main/java/org/seasar/doma/boot/event/DomaEvent.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.event; 2 | 3 | import org.springframework.context.ApplicationEvent; 4 | 5 | /** 6 | * Abstract base class for events emitted by Doma. 7 | */ 8 | public abstract class DomaEvent extends ApplicationEvent { 9 | private final S context; 10 | 11 | protected DomaEvent(T source, S context) { 12 | super(source); 13 | this.context = context; 14 | } 15 | 16 | @Override 17 | @SuppressWarnings("unchecked") 18 | public T getSource() { 19 | return (T) this.source; 20 | } 21 | 22 | public S getContext() { 23 | return this.context; 24 | } 25 | } -------------------------------------------------------------------------------- /doma-spring-boot-core/src/main/java/org/seasar/doma/boot/event/DomaEventEntityListener.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.event; 2 | 3 | import org.seasar.doma.jdbc.entity.*; 4 | import org.springframework.context.ApplicationEventPublisher; 5 | import org.springframework.context.ApplicationEventPublisherAware; 6 | 7 | /** 8 | * {@link EntityListener} implementation that publishes {@link DomaEvent}.
9 | *
10 | * This class extends {@link NullEntityListener} so that {@link org.seasar.doma.Entity} is 11 | * available with default parameters. 12 | * 13 | * @param Entity class 14 | * @author Toshiaki Maki 15 | */ 16 | public class DomaEventEntityListener extends NullEntityListener implements 17 | ApplicationEventPublisherAware { 18 | 19 | private ApplicationEventPublisher eventPublisher; 20 | 21 | @Override 22 | public void preInsert(T t, PreInsertContext context) { 23 | this.eventPublisher.publishEvent(new PreInsertEvent<>(t, context)); 24 | } 25 | 26 | @Override 27 | public void preUpdate(T t, PreUpdateContext context) { 28 | this.eventPublisher.publishEvent(new PreUpdateEvent<>(t, context)); 29 | } 30 | 31 | @Override 32 | public void preDelete(T t, PreDeleteContext context) { 33 | this.eventPublisher.publishEvent(new PreDeleteEvent<>(t, context)); 34 | } 35 | 36 | @Override 37 | public void postInsert(T t, PostInsertContext context) { 38 | this.eventPublisher.publishEvent(new PostInsertEvent<>(t, context)); 39 | } 40 | 41 | @Override 42 | public void postUpdate(T t, PostUpdateContext context) { 43 | this.eventPublisher.publishEvent(new PostUpdateEvent<>(t, context)); 44 | } 45 | 46 | @Override 47 | public void postDelete(T t, PostDeleteContext context) { 48 | this.eventPublisher.publishEvent(new PostDeleteEvent<>(t, context)); 49 | } 50 | 51 | @Override 52 | public void setApplicationEventPublisher(ApplicationEventPublisher eventPublisher) { 53 | this.eventPublisher = eventPublisher; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /doma-spring-boot-core/src/main/java/org/seasar/doma/boot/event/DomaEventListenerFactory.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.event; 2 | 3 | import java.lang.reflect.Method; 4 | import org.seasar.doma.boot.event.annotation.HandleDomaEvent; 5 | import org.springframework.beans.BeansException; 6 | import org.springframework.beans.factory.BeanFactory; 7 | import org.springframework.beans.factory.BeanFactoryAware; 8 | import org.springframework.context.ApplicationListener; 9 | import org.springframework.context.event.EventListenerFactory; 10 | import org.springframework.core.Ordered; 11 | import org.springframework.core.annotation.AnnotationUtils; 12 | 13 | public class DomaEventListenerFactory implements EventListenerFactory, Ordered, 14 | BeanFactoryAware { 15 | 16 | private int order = Ordered.HIGHEST_PRECEDENCE; 17 | private BeanFactory beanFactory; 18 | 19 | @Override 20 | public boolean supportsMethod(Method method) { 21 | return AnnotationUtils.findAnnotation(method, HandleDomaEvent.class) != null; 22 | } 23 | 24 | @Override 25 | public ApplicationListener createApplicationListener(String beanName, 26 | Class type, Method method) { 27 | return new DomaApplicationListener(beanName, method, beanFactory); 28 | } 29 | 30 | @Override 31 | public int getOrder() { 32 | return order; 33 | } 34 | 35 | public void setOrder(int order) { 36 | this.order = order; 37 | } 38 | 39 | @Override 40 | public void setBeanFactory(BeanFactory beanFactory) throws BeansException { 41 | this.beanFactory = beanFactory; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /doma-spring-boot-core/src/main/java/org/seasar/doma/boot/event/PostDeleteEvent.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.event; 2 | 3 | import org.seasar.doma.jdbc.entity.PostDeleteContext; 4 | 5 | public class PostDeleteEvent extends DomaEvent> { 6 | 7 | public PostDeleteEvent(T source, PostDeleteContext context) { 8 | super(source, context); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /doma-spring-boot-core/src/main/java/org/seasar/doma/boot/event/PostInsertEvent.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.event; 2 | 3 | import org.seasar.doma.jdbc.entity.PostInsertContext; 4 | 5 | public class PostInsertEvent extends DomaEvent> { 6 | 7 | public PostInsertEvent(T source, PostInsertContext context) { 8 | super(source, context); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /doma-spring-boot-core/src/main/java/org/seasar/doma/boot/event/PostUpdateEvent.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.event; 2 | 3 | import org.seasar.doma.jdbc.entity.PostUpdateContext; 4 | 5 | public class PostUpdateEvent extends DomaEvent> { 6 | 7 | public PostUpdateEvent(T source, PostUpdateContext context) { 8 | super(source, context); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /doma-spring-boot-core/src/main/java/org/seasar/doma/boot/event/PreDeleteEvent.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.event; 2 | 3 | import org.seasar.doma.jdbc.entity.PreDeleteContext; 4 | 5 | public class PreDeleteEvent extends DomaEvent> { 6 | 7 | public PreDeleteEvent(T source, PreDeleteContext context) { 8 | super(source, context); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /doma-spring-boot-core/src/main/java/org/seasar/doma/boot/event/PreInsertEvent.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.event; 2 | 3 | import org.seasar.doma.jdbc.entity.PreInsertContext; 4 | 5 | public class PreInsertEvent extends DomaEvent> { 6 | 7 | public PreInsertEvent(T source, PreInsertContext context) { 8 | super(source, context); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /doma-spring-boot-core/src/main/java/org/seasar/doma/boot/event/PreUpdateEvent.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.event; 2 | 3 | import org.seasar.doma.jdbc.entity.PreUpdateContext; 4 | 5 | public class PreUpdateEvent extends DomaEvent> { 6 | 7 | public PreUpdateEvent(T source, PreUpdateContext context) { 8 | super(source, context); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /doma-spring-boot-core/src/main/java/org/seasar/doma/boot/event/annotation/HandleDomaEvent.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.event.annotation; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | import org.springframework.context.event.EventListener; 8 | 9 | @EventListener 10 | @Target({ ElementType.ANNOTATION_TYPE }) 11 | @Retention(RetentionPolicy.RUNTIME) 12 | public @interface HandleDomaEvent { 13 | Class contextClass(); 14 | } 15 | -------------------------------------------------------------------------------- /doma-spring-boot-core/src/main/java/org/seasar/doma/boot/event/annotation/HandlePostDelete.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.event.annotation; 2 | 3 | import java.lang.annotation.*; 4 | import org.seasar.doma.jdbc.entity.PostDeleteContext; 5 | 6 | @HandleDomaEvent(contextClass = PostDeleteContext.class) 7 | @Target({ ElementType.TYPE, ElementType.METHOD }) 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Inherited 10 | public @interface HandlePostDelete { 11 | } 12 | -------------------------------------------------------------------------------- /doma-spring-boot-core/src/main/java/org/seasar/doma/boot/event/annotation/HandlePostInsert.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.event.annotation; 2 | 3 | import java.lang.annotation.*; 4 | import org.seasar.doma.jdbc.entity.PostInsertContext; 5 | 6 | @HandleDomaEvent(contextClass = PostInsertContext.class) 7 | @Target({ ElementType.TYPE, ElementType.METHOD }) 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Inherited 10 | public @interface HandlePostInsert { 11 | } 12 | -------------------------------------------------------------------------------- /doma-spring-boot-core/src/main/java/org/seasar/doma/boot/event/annotation/HandlePostUpdate.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.event.annotation; 2 | 3 | import java.lang.annotation.*; 4 | import org.seasar.doma.jdbc.entity.PostUpdateContext; 5 | 6 | @HandleDomaEvent(contextClass = PostUpdateContext.class) 7 | @Target({ ElementType.TYPE, ElementType.METHOD }) 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Inherited 10 | public @interface HandlePostUpdate { 11 | } 12 | -------------------------------------------------------------------------------- /doma-spring-boot-core/src/main/java/org/seasar/doma/boot/event/annotation/HandlePreDelete.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.event.annotation; 2 | 3 | import java.lang.annotation.*; 4 | import org.seasar.doma.jdbc.entity.PreDeleteContext; 5 | 6 | @HandleDomaEvent(contextClass = PreDeleteContext.class) 7 | @Target({ ElementType.TYPE, ElementType.METHOD }) 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Inherited 10 | public @interface HandlePreDelete { 11 | } 12 | -------------------------------------------------------------------------------- /doma-spring-boot-core/src/main/java/org/seasar/doma/boot/event/annotation/HandlePreInsert.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.event.annotation; 2 | 3 | import java.lang.annotation.*; 4 | import org.seasar.doma.jdbc.entity.PreInsertContext; 5 | 6 | @HandleDomaEvent(contextClass = PreInsertContext.class) 7 | @Target({ ElementType.TYPE, ElementType.METHOD }) 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Inherited 10 | public @interface HandlePreInsert { 11 | } 12 | -------------------------------------------------------------------------------- /doma-spring-boot-core/src/main/java/org/seasar/doma/boot/event/annotation/HandlePreUpdate.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.event.annotation; 2 | 3 | import java.lang.annotation.*; 4 | import org.seasar.doma.jdbc.entity.PreUpdateContext; 5 | 6 | @HandleDomaEvent(contextClass = PreUpdateContext.class) 7 | @Target({ ElementType.TYPE, ElementType.METHOD }) 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Inherited 10 | public @interface HandlePreUpdate { 11 | } 12 | -------------------------------------------------------------------------------- /doma-spring-boot-core/src/main/java/org/seasar/doma/boot/event/annotation/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Annotations for {@link org.seasar.doma.boot.event.DomaEvent}. 3 | */ 4 | package org.seasar.doma.boot.event.annotation; 5 | -------------------------------------------------------------------------------- /doma-spring-boot-core/src/main/java/org/seasar/doma/boot/event/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Doma Event Handler. 3 | */ 4 | package org.seasar.doma.boot.event; 5 | -------------------------------------------------------------------------------- /doma-spring-boot-core/src/main/java/org/seasar/doma/boot/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Spring Boot integration with Doma. 3 | */ 4 | package org.seasar.doma.boot; 5 | -------------------------------------------------------------------------------- /doma-spring-boot-core/src/test/java/org/seasar/doma/boot/DomaPersistenceExceptionTranslatorTest.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | import static org.junit.jupiter.api.Assertions.assertInstanceOf; 5 | 6 | import java.sql.SQLException; 7 | import java.util.Collections; 8 | 9 | import org.junit.jupiter.api.Test; 10 | import org.seasar.doma.DomaException; 11 | import org.seasar.doma.jdbc.ConfigException; 12 | import org.seasar.doma.jdbc.NoResultException; 13 | import org.seasar.doma.jdbc.NonSingleColumnException; 14 | import org.seasar.doma.jdbc.NonUniqueResultException; 15 | import org.seasar.doma.jdbc.OptimisticLockException; 16 | import org.seasar.doma.jdbc.ResultMappingException; 17 | import org.seasar.doma.jdbc.SqlExecutionException; 18 | import org.seasar.doma.jdbc.SqlKind; 19 | import org.seasar.doma.jdbc.SqlLogType; 20 | import org.seasar.doma.jdbc.UniqueConstraintException; 21 | import org.seasar.doma.jdbc.UnknownColumnException; 22 | import org.seasar.doma.message.Message; 23 | import org.springframework.dao.DataAccessException; 24 | import org.springframework.dao.DuplicateKeyException; 25 | import org.springframework.dao.EmptyResultDataAccessException; 26 | import org.springframework.dao.IncorrectResultSizeDataAccessException; 27 | import org.springframework.dao.OptimisticLockingFailureException; 28 | import org.springframework.dao.TypeMismatchDataAccessException; 29 | import org.springframework.dao.UncategorizedDataAccessException; 30 | import org.springframework.jdbc.UncategorizedSQLException; 31 | import org.springframework.jdbc.support.SQLExceptionSubclassTranslator; 32 | 33 | class DomaPersistenceExceptionTranslatorTest { 34 | 35 | private final DomaPersistenceExceptionTranslator translator = new DomaPersistenceExceptionTranslator( 36 | new SQLExceptionSubclassTranslator()); 37 | 38 | @Test 39 | void testOccurNotJdbcException() { 40 | DataAccessException dataAccessException = translator 41 | .translateExceptionIfPossible(new DomaException(Message.DOMA2008)); 42 | assertNull(dataAccessException); 43 | } 44 | 45 | @Test 46 | void testOccurSqlExecutionException() { 47 | DataAccessException dataAccessException = translator 48 | .translateExceptionIfPossible(new SqlExecutionException( 49 | SqlLogType.FORMATTED, SqlKind.SELECT, 50 | "select * from todo where todo_id = ?", 51 | "select * from todo where todo_id = '000000001'", 52 | "TodoDao/findOne.sql", new SQLException(), null)); 53 | assertInstanceOf(UncategorizedSQLException.class, dataAccessException); 54 | assertEquals("select * from todo where todo_id = ?", 55 | ((UncategorizedSQLException) dataAccessException).getSql()); 56 | } 57 | 58 | @Test 59 | void testThrowOptimisticLockingFailureException() { 60 | DataAccessException dataAccessException = translator 61 | .translateExceptionIfPossible(new OptimisticLockException( 62 | SqlLogType.FORMATTED, 63 | SqlKind.SELECT, 64 | "update todo set title = ? where todo_id = ? and version = ?", 65 | "update todo set title = 'Modified Title' where todo_id = '000000001' and version = 1", 66 | "TodoDao/update.sql")); 67 | assertInstanceOf(OptimisticLockingFailureException.class, dataAccessException); 68 | } 69 | 70 | @Test 71 | void testThrowDuplicateKeyException() { 72 | DataAccessException dataAccessException = translator 73 | .translateExceptionIfPossible(new UniqueConstraintException( 74 | SqlLogType.FORMATTED, 75 | SqlKind.INSERT, 76 | "insert into todo (todo_id, title) values (?, ?)", 77 | "insert into todo (todo_id, title) values ('000000001', 'Title')", 78 | "TodoDao/insert.sql", new SQLException())); 79 | assertInstanceOf(DuplicateKeyException.class, dataAccessException); 80 | } 81 | 82 | @Test 83 | void testThrowIncorrectResultSizeDataAccessException() { 84 | { 85 | DataAccessException dataAccessException = translator 86 | .translateExceptionIfPossible(new NonUniqueResultException( 87 | SqlLogType.FORMATTED, SqlKind.SELECT, 88 | "select * from todo where created_at = ?", 89 | "select * from todo where created_at = '2016-03-06'", 90 | "TodoDao/findBy.sql")); 91 | assertInstanceOf(IncorrectResultSizeDataAccessException.class, dataAccessException); 92 | } 93 | { 94 | DataAccessException dataAccessException = translator 95 | .translateExceptionIfPossible(new NonSingleColumnException( 96 | SqlLogType.FORMATTED, 97 | SqlKind.SELECT, 98 | "select todo_id, title from todo where created_at = ?", 99 | "select todo_id, title from todo where created_at = '2016-03-06'", 100 | "TodoDao/findBy.sql")); 101 | assertInstanceOf(IncorrectResultSizeDataAccessException.class, dataAccessException); 102 | } 103 | } 104 | 105 | @Test 106 | void testThrowEmptyResultDataAccessException() { 107 | DataAccessException dataAccessException = translator 108 | .translateExceptionIfPossible(new NoResultException(SqlLogType.FORMATTED, 109 | SqlKind.SELECT, "select * from todo where todo_id = ?", 110 | "select * from todo where todo_id = '000000001'", 111 | "TodoDao/findOne.sql")); 112 | assertInstanceOf(EmptyResultDataAccessException.class, dataAccessException); 113 | } 114 | 115 | @Test 116 | void testThrowTypeMismatchDataAccessException() { 117 | { 118 | DataAccessException dataAccessException = translator 119 | .translateExceptionIfPossible(new UnknownColumnException( 120 | SqlLogType.FORMATTED, "todo_id", "todoId", "model.Todo", 121 | SqlKind.SELECT, "select * from todo where created_at = ?", 122 | "select * from todo where created_at = '2016-03-06'", 123 | "TodoDao/findBy.sql")); 124 | assertInstanceOf(TypeMismatchDataAccessException.class, dataAccessException); 125 | } 126 | { 127 | DataAccessException dataAccessException = translator 128 | .translateExceptionIfPossible(new ResultMappingException( 129 | SqlLogType.FORMATTED, 130 | "Todo", 131 | Collections.singletonList("finished"), 132 | Collections.singletonList("modified_at"), 133 | SqlKind.SELECT, 134 | "select todo_id, title from todo where created_at = ?", 135 | "select todo_id, title from todo where created_at = '2016-03-06'", 136 | "TodoDao/findBy.sql")); 137 | assertInstanceOf(TypeMismatchDataAccessException.class, dataAccessException); 138 | } 139 | } 140 | 141 | @Test 142 | void testThrowUncategorizedDataAccessException() { 143 | DataAccessException dataAccessException = translator 144 | .translateExceptionIfPossible(new ConfigException("DomaConfig", 145 | "configure")); 146 | assertInstanceOf(UncategorizedDataAccessException.class, dataAccessException); 147 | } 148 | 149 | } 150 | -------------------------------------------------------------------------------- /doma-spring-boot-core/src/test/java/org/seasar/doma/boot/PageablesTest.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | 5 | import org.junit.jupiter.api.Test; 6 | import org.seasar.doma.jdbc.SelectOptions; 7 | import org.seasar.doma.jdbc.SelectOptionsAccessor; 8 | import org.springframework.data.domain.PageRequest; 9 | 10 | class PageablesTest { 11 | 12 | @Test 13 | void testToSelectOptions() throws Exception { 14 | SelectOptions options = Pageables.toSelectOptions(pageRequest(0, 10)); 15 | assertEquals(0L, SelectOptionsAccessor.getOffset(options)); 16 | assertEquals(10L, SelectOptionsAccessor.getLimit(options)); 17 | } 18 | 19 | @Test 20 | void testToSelectOptions2() throws Exception { 21 | SelectOptions options = Pageables.toSelectOptions(pageRequest(2, 10)); 22 | assertEquals(20L, SelectOptionsAccessor.getOffset(options)); 23 | assertEquals(10L, SelectOptionsAccessor.getLimit(options)); 24 | } 25 | 26 | @Test 27 | void testToSelectOptions3() throws Exception { 28 | SelectOptions options = Pageables.toSelectOptions(pageRequest(2, 5)); 29 | assertEquals(10L, SelectOptionsAccessor.getOffset(options)); 30 | assertEquals(5L, SelectOptionsAccessor.getLimit(options)); 31 | } 32 | 33 | private static PageRequest pageRequest(int page, int size) throws Exception { 34 | try { 35 | // Try PageRequest.of(int, int) added since Spring Data Commons 2.0 36 | return (PageRequest) PageRequest.class.getMethod("of", int.class, int.class) 37 | .invoke(null, page, size); 38 | } catch (@SuppressWarnings("unused") NoSuchMethodException e) { 39 | // If 'of' method is missing (In other words, Spring Data Commons version is 40 | // less than 2.0), 41 | // then it use constructor with two int arguments. 42 | return PageRequest.class.getConstructor(int.class, int.class).newInstance( 43 | page, size); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /doma-spring-boot-core/src/test/java/org/seasar/doma/boot/ResourceLoaderScriptFileLoaderTest.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertNull; 4 | import static org.junit.jupiter.api.Assertions.assertEquals; 5 | import static org.mockito.Mockito.mock; 6 | import static org.mockito.Mockito.when; 7 | 8 | import java.net.URL; 9 | 10 | import org.junit.jupiter.api.Test; 11 | import org.springframework.core.io.Resource; 12 | import org.springframework.core.io.ResourceLoader; 13 | 14 | class ResourceLoaderScriptFileLoaderTest { 15 | 16 | @Test 17 | void testLoadAsURL() throws Exception { 18 | var location = "META-INF/com/example/dao/TestDao/test.script"; 19 | var expectedURL = new URL("file:///" + location); 20 | var resourceLoader = mock(ResourceLoader.class); 21 | var resource = mock(Resource.class); 22 | 23 | when(resourceLoader.getResource(ResourceLoader.CLASSPATH_URL_PREFIX + location)) 24 | .thenReturn(resource); 25 | when(resource.exists()).thenReturn(true); 26 | when(resource.getURL()).thenReturn(expectedURL); 27 | 28 | var sut = new ResourceLoaderScriptFileLoader(resourceLoader); 29 | var actualURL = sut.loadAsURL(location); 30 | assertEquals(expectedURL, actualURL); 31 | } 32 | 33 | @Test 34 | void testLoadAsURLFallback() throws Exception { 35 | var location = "META-INF/com/example/dao/TestDao/test.script"; 36 | var expectedURL = new URL("file:///" + location); 37 | var resourceLoader = mock(ResourceLoader.class); 38 | var resource = mock(Resource.class); 39 | var notExistsResource = mock(Resource.class); 40 | 41 | when(resourceLoader.getResource(ResourceLoader.CLASSPATH_URL_PREFIX + location)) 42 | .thenReturn(notExistsResource); 43 | when(resourceLoader.getResource(ResourceLoader.CLASSPATH_URL_PREFIX + "/" + location)) 44 | .thenReturn(resource); 45 | when(notExistsResource.exists()).thenReturn(false); 46 | when(resource.exists()).thenReturn(true); 47 | when(resource.getURL()).thenReturn(expectedURL); 48 | 49 | var sut = new ResourceLoaderScriptFileLoader(resourceLoader); 50 | var actualURL = sut.loadAsURL(location); 51 | assertEquals(expectedURL, actualURL); 52 | } 53 | 54 | @Test 55 | void testLoadAsURLScriptNotFound() { 56 | var location = "META-INF/com/example/dao/TestDao/test.script"; 57 | var resourceLoader = mock(ResourceLoader.class); 58 | var notExistsResource = mock(Resource.class); 59 | 60 | when(resourceLoader.getResource(ResourceLoader.CLASSPATH_URL_PREFIX + location)) 61 | .thenReturn(notExistsResource); 62 | when(resourceLoader.getResource(ResourceLoader.CLASSPATH_URL_PREFIX + "/" + location)) 63 | .thenReturn(notExistsResource); 64 | when(notExistsResource.exists()).thenReturn(false); 65 | 66 | var sut = new ResourceLoaderScriptFileLoader(resourceLoader); 67 | var actualURL = sut.loadAsURL(location); 68 | assertNull(actualURL); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /doma-spring-boot-core/src/test/java/org/seasar/doma/boot/TryLookupEntityListenerProviderTest.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | import static org.junit.jupiter.api.Assertions.assertThrows; 5 | 6 | import org.junit.jupiter.api.Test; 7 | import org.seasar.doma.jdbc.entity.EntityListener; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.context.ApplicationContext; 10 | import org.springframework.context.annotation.AnnotationConfigApplicationContext; 11 | import org.springframework.context.annotation.Bean; 12 | import org.springframework.stereotype.Component; 13 | 14 | class TryLookupEntityListenerProviderTest { 15 | 16 | @Test 17 | void testManaged() throws Exception { 18 | try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) { 19 | context.register(FooListener.class); 20 | context.refresh(); 21 | TryLookupEntityListenerProvider provider = new TryLookupEntityListenerProvider(); 22 | provider.setApplicationContext(context); 23 | FooListener listener = provider.get(FooListener.class, FooListener::new); 24 | assertTrue(listener.managed); 25 | } 26 | } 27 | 28 | @Test 29 | void testManaged_notUnique() throws Exception { 30 | try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( 31 | FooConfig.class)) { 32 | TryLookupEntityListenerProvider provider = new TryLookupEntityListenerProvider(); 33 | provider.setApplicationContext(context); 34 | assertThrows(IllegalStateException.class, () -> { 35 | provider.get(FooListener.class, FooListener::new); 36 | }); 37 | } 38 | } 39 | 40 | @Test 41 | void testNotManaged() throws Exception { 42 | try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) { 43 | context.refresh(); 44 | TryLookupEntityListenerProvider provider = new TryLookupEntityListenerProvider(); 45 | provider.setApplicationContext(context); 46 | FooListener listener = provider.get(FooListener.class, FooListener::new); 47 | assertFalse(listener.managed); 48 | } 49 | } 50 | 51 | @Component 52 | static class FooListener implements EntityListener { 53 | 54 | final boolean managed; 55 | 56 | // Invoked by Doma 57 | FooListener() { 58 | managed = false; 59 | } 60 | 61 | // Invoked by Spring 62 | @Autowired 63 | FooListener(ApplicationContext context) { 64 | managed = true; 65 | } 66 | } 67 | 68 | static class FooConfig { 69 | @Bean 70 | FooListener foo1() { 71 | return new FooListener(); 72 | } 73 | 74 | @Bean 75 | FooListener foo2() { 76 | return new FooListener(); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /doma-spring-boot-core/src/test/java/org/seasar/doma/boot/UnifiedCriteriaPageableTest.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot; 2 | 3 | import static org.assertj.core.api.Assertions.assertThatThrownBy; 4 | import static org.junit.jupiter.api.Assertions.assertEquals; 5 | import static org.junit.jupiter.api.Assertions.assertNull; 6 | import static org.junit.jupiter.api.Assertions.assertSame; 7 | import static org.mockito.Mockito.inOrder; 8 | import static org.mockito.Mockito.mock; 9 | import static org.mockito.Mockito.times; 10 | import static org.mockito.Mockito.verify; 11 | import static org.mockito.Mockito.verifyNoMoreInteractions; 12 | 13 | import java.util.Optional; 14 | import java.util.function.Consumer; 15 | import java.util.stream.Collectors; 16 | 17 | import org.junit.jupiter.api.Test; 18 | import org.junit.jupiter.params.ParameterizedTest; 19 | import org.junit.jupiter.params.provider.CsvSource; 20 | import org.seasar.doma.Entity; 21 | import org.seasar.doma.Id; 22 | import org.seasar.doma.Metamodel; 23 | import org.seasar.doma.jdbc.criteria.declaration.OrderByNameDeclaration; 24 | import org.springframework.data.domain.PageRequest; 25 | import org.springframework.data.domain.Pageable; 26 | import org.springframework.data.domain.Sort; 27 | 28 | class UnifiedCriteriaPageableTest { 29 | @ParameterizedTest 30 | @CsvSource(value = { 31 | "0 | 10 | 0 | 10", 32 | "2 | 10 | 20 | 10", 33 | "2 | 5 | 10 | 5", 34 | }, delimiter = '|') 35 | void testOffsetAndLimit( 36 | int pageNumber, int pageSize, int expectedOffset, int expectedLimit) { 37 | Pageable pageable = PageRequest.of(pageNumber, pageSize); 38 | UnifiedCriteriaPageable p = UnifiedCriteriaPageable.of(pageable, c -> Optional.empty()); 39 | 40 | Integer offset = p.offset(); 41 | Integer limit = p.limit(); 42 | 43 | assertEquals(expectedOffset, offset); 44 | assertEquals(expectedLimit, limit); 45 | } 46 | 47 | @Test 48 | void testOffsetAndLimitWhenUnpaged() { 49 | Pageable pageable = Pageable.unpaged(); 50 | UnifiedCriteriaPageable p = UnifiedCriteriaPageable.of(pageable, c -> Optional.empty()); 51 | 52 | Integer offset = p.offset(); 53 | Integer limit = p.limit(); 54 | 55 | assertNull(offset); 56 | assertNull(limit); 57 | } 58 | 59 | @Test 60 | void testOrderBy() { 61 | Pageable pageable = PageRequest.of(0, 10, Sort.by("name").ascending()); 62 | Person_ entity = new Person_(); 63 | UnifiedCriteriaPageable p = UnifiedCriteriaPageable.of( 64 | pageable, 65 | propertyName -> switch (propertyName) { 66 | case "name" -> Optional.of(entity.name); 67 | default -> Optional.empty(); 68 | }); 69 | 70 | Consumer consumer = p.orderBy(); 71 | 72 | OrderByNameDeclaration orderByNameDeclaration = mock(OrderByNameDeclaration.class); 73 | consumer.accept(orderByNameDeclaration); 74 | verify(orderByNameDeclaration, times(1)).asc(entity.name); 75 | } 76 | 77 | @Test 78 | void testOrderBy2() { 79 | Pageable pageable = PageRequest.of(0, 10, 80 | Sort.by("name").descending().and(Sort.by("age").ascending())); 81 | Person_ entity = new Person_(); 82 | UnifiedCriteriaPageable p = UnifiedCriteriaPageable.of( 83 | pageable, 84 | propertyName -> switch (propertyName) { 85 | case "name" -> Optional.of(entity.name); 86 | case "age" -> Optional.of(entity.age); 87 | default -> Optional.empty(); 88 | }); 89 | 90 | Consumer consumer = p.orderBy(); 91 | 92 | OrderByNameDeclaration orderByNameDeclaration = mock(OrderByNameDeclaration.class); 93 | consumer.accept(orderByNameDeclaration); 94 | var sortOrderVerifier = inOrder(orderByNameDeclaration); 95 | sortOrderVerifier.verify(orderByNameDeclaration, times(1)).desc(entity.name); 96 | sortOrderVerifier.verify(orderByNameDeclaration, times(1)).asc(entity.age); 97 | } 98 | 99 | @Test 100 | void testOrderByWhenNonSort() { 101 | Pageable pageable = PageRequest.of(0, 10); 102 | UnifiedCriteriaPageable p = UnifiedCriteriaPageable.of( 103 | pageable, 104 | propertyName -> Optional.empty()); 105 | 106 | Consumer consumer = p.orderBy(); 107 | 108 | OrderByNameDeclaration orderByNameDeclaration = mock(OrderByNameDeclaration.class); 109 | consumer.accept(orderByNameDeclaration); 110 | verifyNoMoreInteractions(orderByNameDeclaration); 111 | } 112 | 113 | @Test 114 | void testOrderByWhenNonSortAndSetDefault() { 115 | Pageable pageable = PageRequest.of(0, 10); 116 | Person_ entity = new Person_(); 117 | Consumer defaultOrder = c -> c.asc(entity.id); 118 | UnifiedCriteriaPageable p = UnifiedCriteriaPageable.of( 119 | pageable, 120 | propertyName -> Optional.empty(), 121 | defaultOrder); 122 | 123 | Consumer consumer = p.orderBy(); 124 | 125 | assertSame(defaultOrder, consumer); 126 | } 127 | 128 | @Test 129 | void testOrderBySingleEntity() { 130 | Pageable pageable = PageRequest.of(0, 10, 131 | Sort.by("name").descending().and(Sort.by("age").ascending())); 132 | Person_ entity = new Person_(); 133 | UnifiedCriteriaPageable p = UnifiedCriteriaPageable.from(pageable, entity); 134 | 135 | Consumer consumer = p.orderBy(); 136 | 137 | OrderByNameDeclaration orderByNameDeclaration = mock(OrderByNameDeclaration.class); 138 | consumer.accept(orderByNameDeclaration); 139 | var sortOrderVerifier = inOrder(orderByNameDeclaration); 140 | sortOrderVerifier.verify(orderByNameDeclaration, times(1)).desc(entity.name); 141 | sortOrderVerifier.verify(orderByNameDeclaration, times(1)).asc(entity.age); 142 | } 143 | 144 | @Test 145 | void testOrderByWhenMissingProperties() { 146 | Pageable pageable = PageRequest.of(0, 10, 147 | Sort.by("dog").and(Sort.by("name")).and(Sort.by("cat"))); 148 | Person_ entity = new Person_(); 149 | UnifiedCriteriaPageable p = UnifiedCriteriaPageable.from(pageable, entity); 150 | 151 | Consumer consumer = p.orderBy(); 152 | 153 | OrderByNameDeclaration orderByNameDeclaration = mock(OrderByNameDeclaration.class); 154 | consumer.accept(orderByNameDeclaration); 155 | verify(orderByNameDeclaration, times(1)).asc(entity.name); 156 | } 157 | 158 | @Test 159 | void testOrderByWhenMissingAllProperties() { 160 | Pageable pageable = PageRequest.of(0, 10, 161 | Sort.by("dog").and(Sort.by("cat"))); 162 | Person_ entity = new Person_(); 163 | Consumer defaultOrder = c -> c.desc(entity.age); 164 | UnifiedCriteriaPageable p = UnifiedCriteriaPageable.from(pageable, entity, defaultOrder); 165 | 166 | Consumer consumer = p.orderBy(); 167 | 168 | assertSame(defaultOrder, consumer); 169 | } 170 | 171 | @Test 172 | void testOrderByWhenMissingPropertiesHandle() { 173 | Pageable pageable = PageRequest.of(0, 10, 174 | Sort.by("dog").and(Sort.by("name")).and(Sort.by("cat"))); 175 | Person_ entity = new Person_(); 176 | UnifiedCriteriaPageable p = UnifiedCriteriaPageable.from(pageable, entity); 177 | 178 | assertThatThrownBy(() -> p.orderBy(missingProperties -> { 179 | throw new IllegalArgumentException( 180 | missingProperties.stream().collect(Collectors.joining(","))); 181 | })) 182 | .isInstanceOf(IllegalArgumentException.class) 183 | .hasMessage("dog,cat"); 184 | } 185 | } 186 | 187 | @Entity(metamodel = @Metamodel) 188 | record Person(@Id String id, String name, Integer age) { 189 | } 190 | -------------------------------------------------------------------------------- /doma-spring-boot-jacoco-aggregate/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | org.seasar.doma.boot 9 | doma-spring-boot 10 | 2.5.0-SNAPSHOT 11 | ../pom.xml 12 | 13 | doma-spring-boot-jacoco-aggregate 14 | 15 | 16 | true 17 | 18 | 19 | 20 | 21 | ${project.groupId} 22 | doma-spring-boot-core 23 | ${project.version} 24 | 25 | 26 | ${project.groupId} 27 | doma-spring-boot-autoconfigure 28 | ${project.version} 29 | 30 | 31 | 32 | 33 | 34 | 35 | org.jacoco 36 | jacoco-maven-plugin 37 | 38 | 39 | report-aggregate 40 | verify 41 | 42 | report-aggregate 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-docker-compose/README.md: -------------------------------------------------------------------------------- 1 | # Doma Spring Boot Sample with Docker Compose 2 | 3 | This sample demonstrates how to use Doma with Spring Boot's Docker Compose support. 4 | 5 | ## Requirements 6 | 7 | - Docker 8 | - Docker Compose 9 | 10 | ## How it works 11 | 12 | This sample uses Spring Boot's built-in Docker Compose support, which automatically: 13 | 14 | 1. Detects the `compose.yaml` file in the project root 15 | 2. Starts the PostgreSQL container defined in the compose file 16 | 3. Configures the application to connect to the database 17 | 18 | The `spring-boot-docker-compose` dependency enables this functionality, allowing the application to seamlessly integrate with Docker Compose services. 19 | 20 | ## Running the sample 21 | 22 | From the sample directory, run: 23 | 24 | ```bash 25 | ./mvnw spring-boot:run 26 | ``` 27 | 28 | Spring Boot will automatically: 29 | - Start the PostgreSQL container defined in compose.yaml 30 | - Configure the application to connect to the database 31 | - Run the application 32 | 33 | ## Using the application 34 | 35 | Once the application is running, you can access it at http://localhost:8080 36 | 37 | ### API Endpoints 38 | 39 | - `GET /` - List all messages 40 | - `GET /?text=hello` - Add a new message with the text "hello" 41 | 42 | ## Configuration 43 | 44 | The PostgreSQL configuration is defined in the `compose.yaml` file: 45 | 46 | ```yaml 47 | services: 48 | postgres: 49 | image: 'postgres:latest' 50 | environment: 51 | - 'POSTGRES_DB=mydatabase' 52 | - 'POSTGRES_PASSWORD=secret' 53 | - 'POSTGRES_USER=myuser' 54 | ports: 55 | - '5432' 56 | ``` 57 | 58 | Spring Boot automatically configures the application to connect to this database. 59 | 60 | ## Notes 61 | 62 | - No manual configuration of database connection properties is needed 63 | - The schema.sql file is automatically executed when the application starts 64 | - Spring Boot manages the lifecycle of the Docker containers 65 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-docker-compose/compose.yaml: -------------------------------------------------------------------------------- 1 | services: 2 | postgres: 3 | image: 'postgres:latest' 4 | environment: 5 | - 'POSTGRES_DB=mydatabase' 6 | - 'POSTGRES_PASSWORD=secret' 7 | - 'POSTGRES_USER=myuser' 8 | ports: 9 | - '5432' 10 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-docker-compose/mvnw.cmd: -------------------------------------------------------------------------------- 1 | <# : batch portion 2 | @REM ---------------------------------------------------------------------------- 3 | @REM Licensed to the Apache Software Foundation (ASF) under one 4 | @REM or more contributor license agreements. See the NOTICE file 5 | @REM distributed with this work for additional information 6 | @REM regarding copyright ownership. The ASF licenses this file 7 | @REM to you under the Apache License, Version 2.0 (the 8 | @REM "License"); you may not use this file except in compliance 9 | @REM with the License. You may obtain a copy of the License at 10 | @REM 11 | @REM http://www.apache.org/licenses/LICENSE-2.0 12 | @REM 13 | @REM Unless required by applicable law or agreed to in writing, 14 | @REM software distributed under the License is distributed on an 15 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | @REM KIND, either express or implied. See the License for the 17 | @REM specific language governing permissions and limitations 18 | @REM under the License. 19 | @REM ---------------------------------------------------------------------------- 20 | 21 | @REM ---------------------------------------------------------------------------- 22 | @REM Apache Maven Wrapper startup batch script, version 3.3.2 23 | @REM 24 | @REM Optional ENV vars 25 | @REM MVNW_REPOURL - repo url base for downloading maven distribution 26 | @REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven 27 | @REM MVNW_VERBOSE - true: enable verbose log; others: silence the output 28 | @REM ---------------------------------------------------------------------------- 29 | 30 | @IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) 31 | @SET __MVNW_CMD__= 32 | @SET __MVNW_ERROR__= 33 | @SET __MVNW_PSMODULEP_SAVE=%PSModulePath% 34 | @SET PSModulePath= 35 | @FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( 36 | IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) 37 | ) 38 | @SET PSModulePath=%__MVNW_PSMODULEP_SAVE% 39 | @SET __MVNW_PSMODULEP_SAVE= 40 | @SET __MVNW_ARG0_NAME__= 41 | @SET MVNW_USERNAME= 42 | @SET MVNW_PASSWORD= 43 | @IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) 44 | @echo Cannot start maven from wrapper >&2 && exit /b 1 45 | @GOTO :EOF 46 | : end batch / begin powershell #> 47 | 48 | $ErrorActionPreference = "Stop" 49 | if ($env:MVNW_VERBOSE -eq "true") { 50 | $VerbosePreference = "Continue" 51 | } 52 | 53 | # calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties 54 | $distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl 55 | if (!$distributionUrl) { 56 | Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" 57 | } 58 | 59 | switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { 60 | "maven-mvnd-*" { 61 | $USE_MVND = $true 62 | $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" 63 | $MVN_CMD = "mvnd.cmd" 64 | break 65 | } 66 | default { 67 | $USE_MVND = $false 68 | $MVN_CMD = $script -replace '^mvnw','mvn' 69 | break 70 | } 71 | } 72 | 73 | # apply MVNW_REPOURL and calculate MAVEN_HOME 74 | # maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ 75 | if ($env:MVNW_REPOURL) { 76 | $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } 77 | $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" 78 | } 79 | $distributionUrlName = $distributionUrl -replace '^.*/','' 80 | $distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' 81 | $MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" 82 | if ($env:MAVEN_USER_HOME) { 83 | $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain" 84 | } 85 | $MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' 86 | $MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" 87 | 88 | if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { 89 | Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" 90 | Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" 91 | exit $? 92 | } 93 | 94 | if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { 95 | Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" 96 | } 97 | 98 | # prepare tmp dir 99 | $TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile 100 | $TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" 101 | $TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null 102 | trap { 103 | if ($TMP_DOWNLOAD_DIR.Exists) { 104 | try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } 105 | catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } 106 | } 107 | } 108 | 109 | New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null 110 | 111 | # Download and Install Apache Maven 112 | Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." 113 | Write-Verbose "Downloading from: $distributionUrl" 114 | Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" 115 | 116 | $webclient = New-Object System.Net.WebClient 117 | if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { 118 | $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) 119 | } 120 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 121 | $webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null 122 | 123 | # If specified, validate the SHA-256 sum of the Maven distribution zip file 124 | $distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum 125 | if ($distributionSha256Sum) { 126 | if ($USE_MVND) { 127 | Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." 128 | } 129 | Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash 130 | if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { 131 | Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." 132 | } 133 | } 134 | 135 | # unzip and move 136 | Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null 137 | Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null 138 | try { 139 | Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null 140 | } catch { 141 | if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { 142 | Write-Error "fail to move MAVEN_HOME" 143 | } 144 | } finally { 145 | try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } 146 | catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } 147 | } 148 | 149 | Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" 150 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-docker-compose/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | doma-spring-boot-sample-docker-compose 7 | jar 8 | 9 | doma-spring-boot-sample-docker-compose 10 | Demo project for Spring Boot with Docker Compose 11 | 12 | 13 | org.seasar.doma.boot 14 | doma-spring-boot-samples 15 | 2.5.0-SNAPSHOT 16 | ../pom.xml 17 | 18 | 19 | 20 | 21 | org.seasar.doma 22 | doma-core 23 | ${doma.version} 24 | 25 | 26 | org.seasar.doma 27 | doma-processor 28 | ${doma.version} 29 | true 30 | 31 | 32 | org.seasar.doma.boot 33 | doma-spring-boot-starter 34 | ${project.version} 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-starter-web 39 | 40 | 41 | org.springframework.boot 42 | spring-boot-docker-compose 43 | runtime 44 | true 45 | 46 | 47 | org.postgresql 48 | postgresql 49 | runtime 50 | 51 | 52 | 53 | org.springframework.boot 54 | spring-boot-starter-test 55 | test 56 | 57 | 58 | 59 | 60 | 61 | 62 | org.springframework.boot 63 | spring-boot-maven-plugin 64 | ${spring-boot.version} 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-docker-compose/src/main/java/org/seasar/doma/boot/sample/Application.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class Application { 8 | 9 | @SuppressWarnings("resource") 10 | public static void main(String[] args) { 11 | SpringApplication.run(Application.class, args); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-docker-compose/src/main/java/org/seasar/doma/boot/sample/Message.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import org.seasar.doma.*; 4 | 5 | @Entity 6 | @Table(name = "messages") 7 | public class Message { 8 | @Id 9 | @GeneratedValue(strategy = GenerationType.IDENTITY) 10 | public Integer id; 11 | 12 | public String text; 13 | } 14 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-docker-compose/src/main/java/org/seasar/doma/boot/sample/MessageController.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import java.util.List; 4 | 5 | import org.seasar.doma.boot.Pageables; 6 | import org.springframework.data.domain.Pageable; 7 | import org.springframework.data.web.PageableDefault; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RequestParam; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | @RestController 14 | @RequestMapping("/") 15 | public class MessageController { 16 | 17 | private final MessageDao messageDao; 18 | 19 | public MessageController(MessageDao messageDao) { 20 | this.messageDao = messageDao; 21 | } 22 | 23 | @GetMapping 24 | List list(@PageableDefault Pageable pageable) { 25 | return messageDao.selectAll(Pageables.toSelectOptions(pageable)); 26 | } 27 | 28 | @GetMapping(params = "text") 29 | Message add(@RequestParam String text) { 30 | Message message = new Message(); 31 | message.text = text; 32 | messageDao.insert(message); 33 | return message; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-docker-compose/src/main/java/org/seasar/doma/boot/sample/MessageDao.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import java.util.List; 4 | 5 | import org.seasar.doma.Dao; 6 | import org.seasar.doma.Insert; 7 | import org.seasar.doma.Select; 8 | import org.seasar.doma.boot.ConfigAutowireable; 9 | import org.seasar.doma.jdbc.SelectOptions; 10 | import org.springframework.transaction.annotation.Transactional; 11 | 12 | @Dao 13 | @ConfigAutowireable 14 | @Transactional 15 | public interface MessageDao { 16 | @Select 17 | List selectAll(SelectOptions options); 18 | 19 | @Insert 20 | int insert(Message message); 21 | } 22 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-docker-compose/src/main/resources/META-INF/org/seasar/doma/boot/sample/MessageDao/selectAll.sql: -------------------------------------------------------------------------------- 1 | SELECT id, text FROM messages ORDER BY id; 2 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-docker-compose/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=doma-spring-boot-sample-docker-compose 2 | spring.sql.init.mode=always 3 | spring.docker.compose.skip.in-tests=false 4 | logging.level.org.springframework.jdbc.support.JdbcTransactionManager=DEBUG 5 | logging.level.org.seasar.doma.jdbc=DEBUG 6 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-docker-compose/src/main/resources/schema.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS messages ( 2 | id SERIAL PRIMARY KEY, 3 | text VARCHAR(255) 4 | ); 5 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-docker-compose/src/test/java/org/seasar/doma/boot/sample/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | 5 | import java.util.List; 6 | 7 | import org.junit.jupiter.api.BeforeEach; 8 | import org.junit.jupiter.api.Test; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.boot.test.context.SpringBootTest; 11 | import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; 12 | import org.springframework.boot.test.web.server.LocalServerPort; 13 | import org.springframework.core.ParameterizedTypeReference; 14 | import org.springframework.jdbc.core.simple.JdbcClient; 15 | import org.springframework.web.client.RestClient; 16 | 17 | @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) 18 | class ApplicationTest { 19 | private RestClient restClient; 20 | private final ParameterizedTypeReference> typedReference = new ParameterizedTypeReference<>() { 21 | }; 22 | @LocalServerPort 23 | private int port; 24 | 25 | @BeforeEach 26 | void setUp(@Autowired RestClient.Builder restClientBuilder, @Autowired JdbcClient jdbcClient) { 27 | jdbcClient.sql("DELETE FROM messages").update(); 28 | jdbcClient.sql("ALTER SEQUENCE messages_id_seq RESTART WITH 1").update(); 29 | 30 | this.restClient = restClientBuilder 31 | .baseUrl("http://localhost:" + port) 32 | .defaultStatusHandler(__ -> true, (req, res) -> { 33 | }).build(); 34 | } 35 | 36 | @Test 37 | void testWithDockerCompose() { 38 | Message message1 = restClient.get() 39 | .uri("/?text={text}", "hello") 40 | .retrieve() 41 | .body(Message.class); 42 | assertEquals(1, message1.id); 43 | assertEquals("hello", message1.text); 44 | 45 | Message message2 = restClient.get() 46 | .uri("/?text={text}", "world") 47 | .retrieve() 48 | .body(Message.class); 49 | assertEquals(2, message2.id); 50 | assertEquals("world", message2.text); 51 | 52 | { 53 | List messages = restClient.get() 54 | .uri("/") 55 | .retrieve() 56 | .body(typedReference); 57 | assertEquals(2, messages.size()); 58 | assertEquals(message1.id, messages.get(0).id); 59 | assertEquals(message1.text, messages.get(0).text); 60 | assertEquals(message2.id, messages.get(1).id); 61 | assertEquals(message2.text, messages.get(1).text); 62 | } 63 | 64 | { 65 | List messages = restClient.get() 66 | .uri("/?page={page}&size={size}", 1, 1) 67 | .retrieve() 68 | .body(typedReference); 69 | assertEquals(1, messages.size()); 70 | assertEquals(message2.id, messages.get(0).id); 71 | assertEquals(message2.text, messages.get(0).text); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-entity-listener/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/domaframework/doma-spring-boot/3d75478c299a8b4b55579f23245b2c387b3631ce/doma-spring-boot-samples/doma-spring-boot-sample-entity-listener/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-entity-listener/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.9.10/apache-maven-3.9.10-bin.zip -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-entity-listener/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 40 | 41 | @REM set %HOME% to equivalent of $HOME 42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 43 | 44 | @REM Execute a user defined script before this one 45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 49 | :skipRcPre 50 | 51 | @setlocal 52 | 53 | set ERROR_CODE=0 54 | 55 | @REM To isolate internal variables from possible post scripts, we use another setlocal 56 | @setlocal 57 | 58 | @REM ==== START VALIDATION ==== 59 | if not "%JAVA_HOME%" == "" goto OkJHome 60 | 61 | echo. 62 | echo Error: JAVA_HOME not found in your environment. >&2 63 | echo Please set the JAVA_HOME variable in your environment to match the >&2 64 | echo location of your Java installation. >&2 65 | echo. 66 | goto error 67 | 68 | :OkJHome 69 | if exist "%JAVA_HOME%\bin\java.exe" goto init 70 | 71 | echo. 72 | echo Error: JAVA_HOME is set to an invalid directory. >&2 73 | echo JAVA_HOME = "%JAVA_HOME%" >&2 74 | echo Please set the JAVA_HOME variable in your environment to match the >&2 75 | echo location of your Java installation. >&2 76 | echo. 77 | goto error 78 | 79 | @REM ==== END VALIDATION ==== 80 | 81 | :init 82 | 83 | set MAVEN_CMD_LINE_ARGS=%* 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | 121 | set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar"" 122 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 123 | 124 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS% 125 | if ERRORLEVEL 1 goto error 126 | goto end 127 | 128 | :error 129 | set ERROR_CODE=1 130 | 131 | :end 132 | @endlocal & set ERROR_CODE=%ERROR_CODE% 133 | 134 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 135 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 136 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 137 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 138 | :skipRcPost 139 | 140 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 141 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 142 | 143 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 144 | 145 | exit /B %ERROR_CODE% -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-entity-listener/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | doma-spring-boot-sample-entity-listener 7 | jar 8 | 9 | doma-spring-boot-sample-entity-listener 10 | Demo project for Spring Boot 11 | 12 | 13 | org.seasar.doma.boot 14 | doma-spring-boot-samples 15 | 2.5.0-SNAPSHOT 16 | ../pom.xml 17 | 18 | 19 | 20 | 21 | org.seasar.doma 22 | doma-processor 23 | ${doma.version} 24 | true 25 | 26 | 27 | org.seasar.doma.boot 28 | doma-spring-boot-starter 29 | ${project.version} 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-starter-web 34 | 35 | 36 | com.fasterxml.jackson.datatype 37 | jackson-datatype-jsr310 38 | 39 | 40 | com.h2database 41 | h2 42 | runtime 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-starter-test 47 | test 48 | 49 | 50 | org.junit.jupiter 51 | junit-jupiter 52 | test 53 | 54 | 55 | 56 | 57 | 58 | 59 | org.springframework.boot 60 | spring-boot-maven-plugin 61 | ${spring-boot.version} 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-entity-listener/src/main/java/org/seasar/doma/boot/sample/Application.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class Application { 8 | 9 | @SuppressWarnings("resource") 10 | public static void main(String[] args) { 11 | SpringApplication.run(Application.class, args); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-entity-listener/src/main/java/org/seasar/doma/boot/sample/Message.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import org.seasar.doma.*; 4 | 5 | import java.time.LocalDate; 6 | 7 | @Entity(listener = MessageListener.class) 8 | @Table(name = "messages") 9 | public class Message { 10 | @Id 11 | @GeneratedValue(strategy = GenerationType.IDENTITY) 12 | public Integer id; 13 | 14 | public String text; 15 | 16 | public LocalDate createdAt; 17 | } 18 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-entity-listener/src/main/java/org/seasar/doma/boot/sample/MessageController.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import java.util.List; 4 | 5 | import org.seasar.doma.boot.Pageables; 6 | import org.springframework.data.domain.Pageable; 7 | import org.springframework.data.web.PageableDefault; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RequestParam; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | @RestController 14 | @RequestMapping("/") 15 | public class MessageController { 16 | 17 | private final MessageDao messageDao; 18 | 19 | public MessageController(MessageDao messageDao) { 20 | this.messageDao = messageDao; 21 | } 22 | 23 | @GetMapping 24 | List list(@PageableDefault Pageable pageable) { 25 | return messageDao.selectAll(Pageables.toSelectOptions(pageable)); 26 | } 27 | 28 | @GetMapping(params = "text") 29 | Message add(@RequestParam String text) { 30 | Message message = new Message(); 31 | message.text = text; 32 | messageDao.insert(message); 33 | return message; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-entity-listener/src/main/java/org/seasar/doma/boot/sample/MessageDao.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import java.util.List; 4 | 5 | import org.seasar.doma.Dao; 6 | import org.seasar.doma.Insert; 7 | import org.seasar.doma.Select; 8 | import org.seasar.doma.boot.ConfigAutowireable; 9 | import org.seasar.doma.jdbc.SelectOptions; 10 | import org.springframework.transaction.annotation.Transactional; 11 | 12 | @Dao 13 | @ConfigAutowireable 14 | @Transactional 15 | public interface MessageDao { 16 | @Select 17 | List selectAll(SelectOptions options); 18 | 19 | @Insert 20 | int insert(Message message); 21 | } 22 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-entity-listener/src/main/java/org/seasar/doma/boot/sample/MessageListener.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import java.time.LocalDate; 4 | 5 | import org.seasar.doma.jdbc.entity.EntityListener; 6 | import org.seasar.doma.jdbc.entity.PreInsertContext; 7 | import org.springframework.stereotype.Component; 8 | 9 | @Component 10 | public class MessageListener implements EntityListener { 11 | @Override 12 | public void preInsert(Message message, PreInsertContext context) { 13 | message.createdAt = LocalDate.now(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-entity-listener/src/main/resources/META-INF/org/seasar/doma/boot/sample/MessageDao/selectAll.sql: -------------------------------------------------------------------------------- 1 | SELECT id,text, createdAt FROM messages ORDER BY id; -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-entity-listener/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | doma.dialect=H2 2 | logging.level.org.springframework.jdbc.datasource.DataSourceTransactionManager=DEBUG -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-entity-listener/src/main/resources/schema.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS messages ( 2 | id INT PRIMARY KEY AUTO_INCREMENT, 3 | text VARCHAR(255), 4 | createdAt DATE 5 | ); 6 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-entity-listener/src/test/java/org/seasar/doma/boot/sample/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | 5 | import java.time.LocalDate; 6 | import java.util.List; 7 | 8 | import org.junit.jupiter.api.Test; 9 | import org.springframework.boot.test.context.SpringBootTest; 10 | import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; 11 | import org.springframework.boot.test.web.client.TestRestTemplate; 12 | import org.springframework.boot.test.web.server.LocalServerPort; 13 | import org.springframework.core.ParameterizedTypeReference; 14 | import org.springframework.http.HttpEntity; 15 | import org.springframework.http.HttpMethod; 16 | import org.springframework.web.util.UriComponentsBuilder; 17 | 18 | @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) 19 | class ApplicationTest { 20 | private final TestRestTemplate restTemplate = new TestRestTemplate(); 21 | private final ParameterizedTypeReference> typedReference = new ParameterizedTypeReference>() { 22 | }; 23 | @LocalServerPort 24 | private int port; 25 | 26 | @Test 27 | void test() { 28 | LocalDate now = LocalDate.now(); 29 | Message message1 = restTemplate.getForObject( 30 | UriComponentsBuilder.fromUriString("http://localhost").port(port) 31 | .queryParam("text", "hello").build().toUri(), 32 | Message.class); 33 | assertEquals(1, message1.id); 34 | assertEquals("hello", message1.text); 35 | assertEquals(now, message1.createdAt); 36 | Message message2 = restTemplate.getForObject( 37 | UriComponentsBuilder.fromUriString("http://localhost").port(port) 38 | .queryParam("text", "world").build().toUri(), 39 | Message.class); 40 | assertEquals(2, message2.id); 41 | assertEquals("world", message2.text); 42 | assertEquals(now, message2.createdAt); 43 | 44 | { 45 | List messages = restTemplate.exchange( 46 | UriComponentsBuilder.fromUriString("http://localhost").port(port) 47 | .build().toUri(), 48 | HttpMethod.GET, HttpEntity.EMPTY, 49 | typedReference).getBody(); 50 | assertEquals(2, messages.size()); 51 | assertEquals(message1.id, messages.get(0).id); 52 | assertEquals(message1.text, messages.get(0).text); 53 | assertEquals(message2.id, messages.get(1).id); 54 | assertEquals(message2.text, messages.get(1).text); 55 | } 56 | 57 | { 58 | List messages = restTemplate.exchange( 59 | UriComponentsBuilder.fromUriString("http://localhost").port(port) 60 | .queryParam("page", "1").queryParam("size", "1").build() 61 | .toUri(), 62 | HttpMethod.GET, HttpEntity.EMPTY, typedReference) 63 | .getBody(); 64 | assertEquals(1, messages.size()); 65 | assertEquals(message2.id, messages.get(0).id); 66 | assertEquals(message2.text, messages.get(0).text); 67 | } 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-event-handler/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/domaframework/doma-spring-boot/3d75478c299a8b4b55579f23245b2c387b3631ce/doma-spring-boot-samples/doma-spring-boot-sample-event-handler/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-event-handler/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.9.10/apache-maven-3.9.10-bin.zip -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-event-handler/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | doma-spring-boot-sample-event-handler 7 | jar 8 | 9 | doma-spring-boot-sample-event-handler 10 | Demo project for Spring Boot 11 | 12 | 13 | org.seasar.doma.boot 14 | doma-spring-boot-samples 15 | 2.5.0-SNAPSHOT 16 | ../pom.xml 17 | 18 | 19 | 20 | 21 | org.seasar.doma 22 | doma-processor 23 | ${doma.version} 24 | true 25 | 26 | 27 | org.seasar.doma.boot 28 | doma-spring-boot-starter 29 | ${project.version} 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-starter-web 34 | 35 | 36 | com.fasterxml.jackson.datatype 37 | jackson-datatype-jsr310 38 | 39 | 40 | com.h2database 41 | h2 42 | runtime 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-starter-test 47 | test 48 | 49 | 50 | org.junit.jupiter 51 | junit-jupiter 52 | test 53 | 54 | 55 | 56 | 57 | 58 | 59 | org.springframework.boot 60 | spring-boot-maven-plugin 61 | ${spring-boot.version} 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-event-handler/src/main/java/org/seasar/doma/boot/sample/Application.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class Application { 8 | 9 | @SuppressWarnings("resource") 10 | public static void main(String[] args) { 11 | SpringApplication.run(Application.class, args); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-event-handler/src/main/java/org/seasar/doma/boot/sample/Message.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import java.time.LocalDate; 4 | 5 | import org.seasar.doma.*; 6 | 7 | @Entity 8 | @Table(name = "messages") 9 | public class Message { 10 | @Id 11 | @GeneratedValue(strategy = GenerationType.IDENTITY) 12 | public Integer id; 13 | 14 | public String text; 15 | 16 | public LocalDate createdAt; 17 | } 18 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-event-handler/src/main/java/org/seasar/doma/boot/sample/MessageController.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import java.util.List; 4 | 5 | import org.seasar.doma.boot.Pageables; 6 | import org.springframework.data.domain.Pageable; 7 | import org.springframework.data.web.PageableDefault; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RequestParam; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | @RestController 14 | @RequestMapping("/") 15 | public class MessageController { 16 | 17 | private final MessageDao messageDao; 18 | 19 | public MessageController(MessageDao messageDao) { 20 | this.messageDao = messageDao; 21 | } 22 | 23 | @GetMapping 24 | List list(@PageableDefault Pageable pageable) { 25 | return messageDao.selectAll(Pageables.toSelectOptions(pageable)); 26 | } 27 | 28 | @GetMapping(params = "text") 29 | Message add(@RequestParam String text) { 30 | Message message = new Message(); 31 | message.text = text; 32 | messageDao.insert(message); 33 | return message; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-event-handler/src/main/java/org/seasar/doma/boot/sample/MessageDao.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import java.util.List; 4 | 5 | import org.seasar.doma.Dao; 6 | import org.seasar.doma.Insert; 7 | import org.seasar.doma.Select; 8 | import org.seasar.doma.boot.ConfigAutowireable; 9 | import org.seasar.doma.jdbc.SelectOptions; 10 | import org.springframework.transaction.annotation.Transactional; 11 | 12 | @Dao 13 | @ConfigAutowireable 14 | @Transactional 15 | public interface MessageDao { 16 | @Select 17 | List selectAll(SelectOptions options); 18 | 19 | @Insert 20 | int insert(Message message); 21 | } 22 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-event-handler/src/main/java/org/seasar/doma/boot/sample/MessageHandler.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import java.time.LocalDate; 4 | 5 | import org.seasar.doma.boot.event.annotation.HandlePreInsert; 6 | import org.springframework.stereotype.Component; 7 | 8 | @Component 9 | public class MessageHandler { 10 | @HandlePreInsert 11 | public void preInsert(Message message) { 12 | message.createdAt = LocalDate.now(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-event-handler/src/main/resources/META-INF/org/seasar/doma/boot/sample/MessageDao/selectAll.sql: -------------------------------------------------------------------------------- 1 | SELECT id,text, createdAt FROM messages ORDER BY id; -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-event-handler/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | doma.dialect=H2 2 | logging.level.org.springframework.jdbc.datasource.DataSourceTransactionManager=DEBUG -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-event-handler/src/main/resources/schema.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS messages ( 2 | id INT PRIMARY KEY AUTO_INCREMENT, 3 | text VARCHAR(255), 4 | createdAt DATE 5 | ); 6 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-event-handler/src/test/java/org/seasar/doma/boot/sample/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | 5 | import java.time.LocalDate; 6 | import java.util.List; 7 | 8 | import org.junit.jupiter.api.Test; 9 | import org.springframework.boot.test.context.SpringBootTest; 10 | import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; 11 | import org.springframework.boot.test.web.client.TestRestTemplate; 12 | import org.springframework.boot.test.web.server.LocalServerPort; 13 | import org.springframework.core.ParameterizedTypeReference; 14 | import org.springframework.http.HttpEntity; 15 | import org.springframework.http.HttpMethod; 16 | import org.springframework.web.util.UriComponentsBuilder; 17 | 18 | @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) 19 | class ApplicationTest { 20 | private final TestRestTemplate restTemplate = new TestRestTemplate(); 21 | private final ParameterizedTypeReference> typedReference = new ParameterizedTypeReference>() { 22 | }; 23 | @LocalServerPort 24 | private int port; 25 | 26 | @Test 27 | void test() { 28 | LocalDate now = LocalDate.now(); 29 | Message message1 = restTemplate.getForObject( 30 | UriComponentsBuilder.fromUriString("http://localhost").port(port) 31 | .queryParam("text", "hello").build().toUri(), 32 | Message.class); 33 | assertEquals(1, message1.id); 34 | assertEquals("hello", message1.text); 35 | assertEquals(now, message1.createdAt); 36 | Message message2 = restTemplate.getForObject( 37 | UriComponentsBuilder.fromUriString("http://localhost").port(port) 38 | .queryParam("text", "world").build().toUri(), 39 | Message.class); 40 | assertEquals(2, message2.id); 41 | assertEquals("world", message2.text); 42 | assertEquals(now, message2.createdAt); 43 | 44 | { 45 | List messages = restTemplate.exchange( 46 | UriComponentsBuilder.fromUriString("http://localhost").port(port) 47 | .build().toUri(), 48 | HttpMethod.GET, HttpEntity.EMPTY, 49 | typedReference).getBody(); 50 | assertEquals(2, messages.size()); 51 | assertEquals(message1.id, messages.get(0).id); 52 | assertEquals(message1.text, messages.get(0).text); 53 | assertEquals(message2.id, messages.get(1).id); 54 | assertEquals(message2.text, messages.get(1).text); 55 | } 56 | 57 | { 58 | List messages = restTemplate.exchange( 59 | UriComponentsBuilder.fromUriString("http://localhost").port(port) 60 | .queryParam("page", "1").queryParam("size", "1").build() 61 | .toUri(), 62 | HttpMethod.GET, HttpEntity.EMPTY, typedReference) 63 | .getBody(); 64 | assertEquals(1, messages.size()); 65 | assertEquals(message2.id, messages.get(0).id); 66 | assertEquals(message2.text, messages.get(0).text); 67 | } 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-simple/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/domaframework/doma-spring-boot/3d75478c299a8b4b55579f23245b2c387b3631ce/doma-spring-boot-samples/doma-spring-boot-sample-simple/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-simple/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.9.10/apache-maven-3.9.10-bin.zip -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-simple/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 40 | 41 | @REM set %HOME% to equivalent of $HOME 42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 43 | 44 | @REM Execute a user defined script before this one 45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 49 | :skipRcPre 50 | 51 | @setlocal 52 | 53 | set ERROR_CODE=0 54 | 55 | @REM To isolate internal variables from possible post scripts, we use another setlocal 56 | @setlocal 57 | 58 | @REM ==== START VALIDATION ==== 59 | if not "%JAVA_HOME%" == "" goto OkJHome 60 | 61 | echo. 62 | echo Error: JAVA_HOME not found in your environment. >&2 63 | echo Please set the JAVA_HOME variable in your environment to match the >&2 64 | echo location of your Java installation. >&2 65 | echo. 66 | goto error 67 | 68 | :OkJHome 69 | if exist "%JAVA_HOME%\bin\java.exe" goto init 70 | 71 | echo. 72 | echo Error: JAVA_HOME is set to an invalid directory. >&2 73 | echo JAVA_HOME = "%JAVA_HOME%" >&2 74 | echo Please set the JAVA_HOME variable in your environment to match the >&2 75 | echo location of your Java installation. >&2 76 | echo. 77 | goto error 78 | 79 | @REM ==== END VALIDATION ==== 80 | 81 | :init 82 | 83 | set MAVEN_CMD_LINE_ARGS=%* 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | 121 | set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar"" 122 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 123 | 124 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS% 125 | if ERRORLEVEL 1 goto error 126 | goto end 127 | 128 | :error 129 | set ERROR_CODE=1 130 | 131 | :end 132 | @endlocal & set ERROR_CODE=%ERROR_CODE% 133 | 134 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 135 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 136 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 137 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 138 | :skipRcPost 139 | 140 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 141 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 142 | 143 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 144 | 145 | exit /B %ERROR_CODE% -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-simple/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | doma-spring-boot-sample-simple 7 | jar 8 | 9 | doma-spring-boot-sample-simple 10 | Demo project for Spring Boot 11 | 12 | 13 | org.seasar.doma.boot 14 | doma-spring-boot-samples 15 | 2.5.0-SNAPSHOT 16 | ../pom.xml 17 | 18 | 19 | 20 | 21 | org.seasar.doma 22 | doma-core 23 | ${doma.version} 24 | 25 | 26 | org.seasar.doma 27 | doma-processor 28 | ${doma.version} 29 | true 30 | 31 | 32 | org.seasar.doma.boot 33 | doma-spring-boot-starter 34 | ${project.version} 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-starter-web 39 | 40 | 41 | com.h2database 42 | h2 43 | runtime 44 | 45 | 46 | org.springframework.boot 47 | spring-boot-starter-test 48 | test 49 | 50 | 51 | org.junit.jupiter 52 | junit-jupiter 53 | test 54 | 55 | 56 | 57 | 58 | 59 | 60 | org.springframework.boot 61 | spring-boot-maven-plugin 62 | ${spring-boot.version} 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-simple/src/main/java/org/seasar/doma/boot/sample/Application.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class Application { 8 | 9 | @SuppressWarnings("resource") 10 | public static void main(String[] args) { 11 | SpringApplication.run(Application.class, args); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-simple/src/main/java/org/seasar/doma/boot/sample/Message.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import org.seasar.doma.*; 4 | 5 | @Entity 6 | @Table(name = "messages") 7 | public class Message { 8 | @Id 9 | @GeneratedValue(strategy = GenerationType.IDENTITY) 10 | public Integer id; 11 | 12 | public String text; 13 | } 14 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-simple/src/main/java/org/seasar/doma/boot/sample/MessageController.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import java.util.List; 4 | 5 | import org.seasar.doma.boot.Pageables; 6 | import org.springframework.data.domain.Pageable; 7 | import org.springframework.data.web.PageableDefault; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RequestParam; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | @RestController 14 | @RequestMapping("/") 15 | public class MessageController { 16 | 17 | private final MessageDao messageDao; 18 | 19 | public MessageController(MessageDao messageDao) { 20 | this.messageDao = messageDao; 21 | } 22 | 23 | @GetMapping 24 | List list(@PageableDefault Pageable pageable) { 25 | return messageDao.selectAll(Pageables.toSelectOptions(pageable)); 26 | } 27 | 28 | @GetMapping(params = "text") 29 | Message add(@RequestParam String text) { 30 | Message message = new Message(); 31 | message.text = text; 32 | messageDao.insert(message); 33 | return message; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-simple/src/main/java/org/seasar/doma/boot/sample/MessageDao.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import java.util.List; 4 | 5 | import org.seasar.doma.Dao; 6 | import org.seasar.doma.Insert; 7 | import org.seasar.doma.Select; 8 | import org.seasar.doma.boot.ConfigAutowireable; 9 | import org.seasar.doma.jdbc.SelectOptions; 10 | import org.springframework.transaction.annotation.Transactional; 11 | 12 | @Dao 13 | @ConfigAutowireable 14 | @Transactional 15 | public interface MessageDao { 16 | @Select 17 | List selectAll(SelectOptions options); 18 | 19 | @Insert 20 | int insert(Message message); 21 | } 22 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-simple/src/main/resources/META-INF/org/seasar/doma/boot/sample/MessageDao/selectAll.sql: -------------------------------------------------------------------------------- 1 | SELECT id,text FROM messages ORDER BY id; -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-simple/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | doma.dialect=H2 2 | logging.level.org.springframework.jdbc.datasource.DataSourceTransactionManager=DEBUG -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-simple/src/main/resources/schema.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS messages ( 2 | id INT PRIMARY KEY AUTO_INCREMENT, 3 | text VARCHAR(255) 4 | ); 5 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-simple/src/test/java/org/seasar/doma/boot/sample/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | 5 | import java.util.List; 6 | 7 | import org.junit.jupiter.api.Test; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.boot.test.context.SpringBootTest; 10 | import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; 11 | import org.springframework.boot.test.web.client.TestRestTemplate; 12 | import org.springframework.boot.test.web.server.LocalServerPort; 13 | import org.springframework.core.ParameterizedTypeReference; 14 | import org.springframework.http.HttpEntity; 15 | import org.springframework.http.HttpMethod; 16 | import org.springframework.web.util.UriComponentsBuilder; 17 | 18 | @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) 19 | class ApplicationTest { 20 | @Autowired 21 | private TestRestTemplate restTemplate; 22 | private final ParameterizedTypeReference> typedReference = new ParameterizedTypeReference>() { 23 | }; 24 | @LocalServerPort 25 | private int port; 26 | 27 | @Test 28 | void test() { 29 | Message message1 = restTemplate.getForObject( 30 | UriComponentsBuilder.fromUriString("http://localhost").port(port) 31 | .queryParam("text", "hello").build().toUri(), 32 | Message.class); 33 | assertEquals(1, message1.id); 34 | assertEquals("hello", message1.text); 35 | Message message2 = restTemplate.getForObject( 36 | UriComponentsBuilder.fromUriString("http://localhost").port(port) 37 | .queryParam("text", "world").build().toUri(), 38 | Message.class); 39 | assertEquals(2, message2.id); 40 | assertEquals("world", message2.text); 41 | 42 | { 43 | List messages = restTemplate.exchange( 44 | UriComponentsBuilder.fromUriString("http://localhost").port(port) 45 | .build().toUri(), 46 | HttpMethod.GET, HttpEntity.EMPTY, 47 | typedReference).getBody(); 48 | assertEquals(2, messages.size()); 49 | assertEquals(message1.id, messages.get(0).id); 50 | assertEquals(message1.text, messages.get(0).text); 51 | assertEquals(message2.id, messages.get(1).id); 52 | assertEquals(message2.text, messages.get(1).text); 53 | } 54 | 55 | { 56 | List messages = restTemplate.exchange( 57 | UriComponentsBuilder.fromUriString("http://localhost").port(port) 58 | .queryParam("page", "1").queryParam("size", "1").build() 59 | .toUri(), 60 | HttpMethod.GET, HttpEntity.EMPTY, typedReference) 61 | .getBody(); 62 | assertEquals(1, messages.size()); 63 | assertEquals(message2.id, messages.get(0).id); 64 | assertEquals(message2.text, messages.get(0).text); 65 | } 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-testcontainers/.mvn/wrapper/MavenWrapperDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-present 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 | * http://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 | import java.net.*; 17 | import java.io.*; 18 | import java.nio.channels.*; 19 | import java.util.Properties; 20 | 21 | public class MavenWrapperDownloader { 22 | 23 | private static final String WRAPPER_VERSION = "0.5.6"; 24 | /** 25 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. 26 | */ 27 | private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" 28 | + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; 29 | 30 | /** 31 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to 32 | * use instead of the default one. 33 | */ 34 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = 35 | ".mvn/wrapper/maven-wrapper.properties"; 36 | 37 | /** 38 | * Path where the maven-wrapper.jar will be saved to. 39 | */ 40 | private static final String MAVEN_WRAPPER_JAR_PATH = 41 | ".mvn/wrapper/maven-wrapper.jar"; 42 | 43 | /** 44 | * Name of the property which should be used to override the default download url for the wrapper. 45 | */ 46 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; 47 | 48 | public static void main(String args[]) { 49 | System.out.println("- Downloader started"); 50 | File baseDirectory = new File(args[0]); 51 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); 52 | 53 | // If the maven-wrapper.properties exists, read it and check if it contains a custom 54 | // wrapperUrl parameter. 55 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); 56 | String url = DEFAULT_DOWNLOAD_URL; 57 | if(mavenWrapperPropertyFile.exists()) { 58 | FileInputStream mavenWrapperPropertyFileInputStream = null; 59 | try { 60 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); 61 | Properties mavenWrapperProperties = new Properties(); 62 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); 63 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); 64 | } catch (IOException e) { 65 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); 66 | } finally { 67 | try { 68 | if(mavenWrapperPropertyFileInputStream != null) { 69 | mavenWrapperPropertyFileInputStream.close(); 70 | } 71 | } catch (IOException e) { 72 | // Ignore ... 73 | } 74 | } 75 | } 76 | System.out.println("- Downloading from: " + url); 77 | 78 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); 79 | if(!outputFile.getParentFile().exists()) { 80 | if(!outputFile.getParentFile().mkdirs()) { 81 | System.out.println( 82 | "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); 83 | } 84 | } 85 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); 86 | try { 87 | downloadFileFromURL(url, outputFile); 88 | System.out.println("Done"); 89 | System.exit(0); 90 | } catch (Throwable e) { 91 | System.out.println("- Error downloading"); 92 | e.printStackTrace(); 93 | System.exit(1); 94 | } 95 | } 96 | 97 | private static void downloadFileFromURL(String urlString, File destination) throws Exception { 98 | if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { 99 | String username = System.getenv("MVNW_USERNAME"); 100 | char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); 101 | Authenticator.setDefault(new Authenticator() { 102 | @Override 103 | protected PasswordAuthentication getPasswordAuthentication() { 104 | return new PasswordAuthentication(username, password); 105 | } 106 | }); 107 | } 108 | URL website = new URL(urlString); 109 | ReadableByteChannel rbc; 110 | rbc = Channels.newChannel(website.openStream()); 111 | FileOutputStream fos = new FileOutputStream(destination); 112 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 113 | fos.close(); 114 | rbc.close(); 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-testcontainers/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/domaframework/doma-spring-boot/3d75478c299a8b4b55579f23245b2c387b3631ce/doma-spring-boot-samples/doma-spring-boot-sample-testcontainers/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-testcontainers/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.10/apache-maven-3.9.10-bin.zip 18 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-testcontainers/README.md: -------------------------------------------------------------------------------- 1 | # Doma Spring Boot Sample with TestContainers 2 | 3 | This sample demonstrates how to use [TestContainers](https://www.testcontainers.org/) with Doma and Spring Boot. 4 | 5 | ## Running the Sample 6 | 7 | To run this sample, you need: 8 | - Java 17 or later 9 | - Maven 10 | - Docker (for running TestContainers) 11 | 12 | ### Build and Run Tests 13 | 14 | This project uses the Maven Wrapper, so you don't need to install Maven separately. 15 | 16 | ```bash 17 | ./mvnw clean test 18 | ``` 19 | 20 | ### Run with TestContainers 21 | 22 | ```bash 23 | ./mvnw spring-boot:test-run 24 | ``` 25 | 26 | This will start the application with a PostgreSQL container. 27 | 28 | ## Features Demonstrated 29 | 30 | - Using TestContainers to start a PostgreSQL database for tests 31 | - Spring Boot's native TestContainers integration with `@ServiceConnection` 32 | - Using TestContainers at development time with `SpringApplication.from()` 33 | - Running Doma queries against a real PostgreSQL database in tests 34 | - Configuration for PostgreSQL database in both development and test environments 35 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-testcontainers/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | doma-spring-boot-sample-testcontainers 7 | jar 8 | 9 | doma-spring-boot-sample-testcontainers 10 | Demo project for Spring Boot with Doma and TestContainers 11 | 12 | 13 | org.seasar.doma.boot 14 | doma-spring-boot-samples 15 | 2.5.0-SNAPSHOT 16 | ../pom.xml 17 | 18 | 19 | 20 | 21 | org.seasar.doma 22 | doma-core 23 | ${doma.version} 24 | 25 | 26 | org.seasar.doma 27 | doma-processor 28 | ${doma.version} 29 | true 30 | 31 | 32 | org.seasar.doma.boot 33 | doma-spring-boot-starter 34 | ${project.version} 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-starter-web 39 | 40 | 41 | org.postgresql 42 | postgresql 43 | runtime 44 | 45 | 46 | org.springframework.boot 47 | spring-boot-starter-test 48 | test 49 | 50 | 51 | org.springframework.boot 52 | spring-boot-testcontainers 53 | test 54 | 55 | 56 | org.testcontainers 57 | postgresql 58 | test 59 | 60 | 61 | 62 | 63 | 64 | 65 | org.springframework.boot 66 | spring-boot-maven-plugin 67 | ${spring-boot.version} 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-testcontainers/src/main/java/org/seasar/doma/boot/sample/Application.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class Application { 8 | 9 | @SuppressWarnings("resource") 10 | public static void main(String[] args) { 11 | SpringApplication.run(Application.class, args); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-testcontainers/src/main/java/org/seasar/doma/boot/sample/Message.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import org.seasar.doma.*; 4 | 5 | @Entity 6 | @Table(name = "messages") 7 | public class Message { 8 | @Id 9 | @GeneratedValue(strategy = GenerationType.IDENTITY) 10 | public Integer id; 11 | 12 | public String text; 13 | } 14 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-testcontainers/src/main/java/org/seasar/doma/boot/sample/MessageController.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import java.util.List; 4 | 5 | import org.seasar.doma.boot.Pageables; 6 | import org.springframework.data.domain.Pageable; 7 | import org.springframework.data.web.PageableDefault; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RequestParam; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | @RestController 14 | @RequestMapping(path = "/") 15 | public class MessageController { 16 | 17 | private final MessageDao messageDao; 18 | 19 | public MessageController(MessageDao messageDao) { 20 | this.messageDao = messageDao; 21 | } 22 | 23 | @GetMapping 24 | List list(@PageableDefault Pageable pageable) { 25 | return messageDao.selectAll(Pageables.toSelectOptions(pageable)); 26 | } 27 | 28 | @GetMapping(params = "text") 29 | Message add(@RequestParam String text) { 30 | Message message = new Message(); 31 | message.text = text; 32 | messageDao.insert(message); 33 | return message; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-testcontainers/src/main/java/org/seasar/doma/boot/sample/MessageDao.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import java.util.List; 4 | 5 | import org.seasar.doma.Dao; 6 | import org.seasar.doma.Insert; 7 | import org.seasar.doma.Select; 8 | import org.seasar.doma.boot.ConfigAutowireable; 9 | import org.seasar.doma.jdbc.SelectOptions; 10 | import org.springframework.transaction.annotation.Transactional; 11 | 12 | @Dao 13 | @ConfigAutowireable 14 | @Transactional 15 | public interface MessageDao { 16 | @Select 17 | List selectAll(SelectOptions options); 18 | 19 | @Insert 20 | int insert(Message message); 21 | } 22 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-testcontainers/src/main/resources/META-INF/org/seasar/doma/boot/sample/MessageDao/selectAll.sql: -------------------------------------------------------------------------------- 1 | SELECT id, text FROM messages ORDER BY id; 2 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-testcontainers/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.sql.init.mode=always 2 | 3 | # Doma configuration 4 | doma.naming=SNAKE_LOWER_CASE 5 | logging.level.org.springframework.jdbc.support.JdbcTransactionManager=DEBUG 6 | logging.level.org.seasar.doma.jdbc=DEBUG 7 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-testcontainers/src/main/resources/schema.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS messages ( 2 | id SERIAL PRIMARY KEY, 3 | text VARCHAR(255) 4 | ); 5 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-testcontainers/src/test/java/org/seasar/doma/boot/sample/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | 5 | import java.util.List; 6 | 7 | import org.junit.jupiter.api.BeforeEach; 8 | import org.junit.jupiter.api.Test; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.boot.test.context.SpringBootTest; 11 | import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; 12 | import org.springframework.boot.test.web.server.LocalServerPort; 13 | import org.springframework.context.annotation.Import; 14 | import org.springframework.core.ParameterizedTypeReference; 15 | import org.springframework.web.client.RestClient; 16 | import org.springframework.web.util.UriComponentsBuilder; 17 | 18 | @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) 19 | @Import(TestcontainersConfiguration.class) 20 | class ApplicationTest { 21 | private RestClient restClient; 22 | private final ParameterizedTypeReference> typedReference = new ParameterizedTypeReference<>() { 23 | }; 24 | @LocalServerPort 25 | private int port; 26 | 27 | @BeforeEach 28 | void setUp(@Autowired RestClient.Builder restClientBuilder) { 29 | this.restClient = restClientBuilder 30 | .baseUrl("http://localhost:" + port) 31 | .defaultStatusHandler(__ -> true, (req, res) -> { 32 | }).build(); 33 | } 34 | 35 | @Test 36 | void testWithTestContainers() { 37 | Message message1 = restClient.get() 38 | .uri("/?text={text}", "hello") 39 | .retrieve() 40 | .body(Message.class); 41 | assertEquals(1, message1.id); 42 | assertEquals("hello", message1.text); 43 | 44 | Message message2 = restClient.get() 45 | .uri("/?text={text}", "world") 46 | .retrieve() 47 | .body(Message.class); 48 | assertEquals(2, message2.id); 49 | assertEquals("world", message2.text); 50 | 51 | { 52 | List messages = restClient.get() 53 | .uri("/") 54 | .retrieve() 55 | .body(typedReference); 56 | assertEquals(2, messages.size()); 57 | assertEquals(message1.id, messages.get(0).id); 58 | assertEquals(message1.text, messages.get(0).text); 59 | assertEquals(message2.id, messages.get(1).id); 60 | assertEquals(message2.text, messages.get(1).text); 61 | } 62 | 63 | { 64 | List messages = restClient.get() 65 | .uri("/?page={page}&size={size}", 1, 1) 66 | .retrieve() 67 | .body(typedReference); 68 | assertEquals(1, messages.size()); 69 | assertEquals(message2.id, messages.get(0).id); 70 | assertEquals(message2.text, messages.get(0).text); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-testcontainers/src/test/java/org/seasar/doma/boot/sample/TestApplication.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | 5 | public class TestApplication { 6 | 7 | public static void main(String[] args) { 8 | SpringApplication.from(Application::main).with(TestcontainersConfiguration.class).run(args); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-testcontainers/src/test/java/org/seasar/doma/boot/sample/TestcontainersConfiguration.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import org.springframework.boot.test.context.TestConfiguration; 4 | import org.springframework.boot.testcontainers.service.connection.ServiceConnection; 5 | import org.springframework.context.annotation.Bean; 6 | import org.testcontainers.containers.PostgreSQLContainer; 7 | import org.testcontainers.utility.DockerImageName; 8 | 9 | @TestConfiguration(proxyBeanMethods = false) 10 | class TestcontainersConfiguration { 11 | 12 | @Bean 13 | @ServiceConnection 14 | PostgreSQLContainer postgresContainer() { 15 | return new PostgreSQLContainer<>(DockerImageName.parse("postgres:latest")); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-two-datasource/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/domaframework/doma-spring-boot/3d75478c299a8b4b55579f23245b2c387b3631ce/doma-spring-boot-samples/doma-spring-boot-sample-two-datasource/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-two-datasource/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.9.10/apache-maven-3.9.10-bin.zip -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-two-datasource/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 40 | 41 | @REM set %HOME% to equivalent of $HOME 42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 43 | 44 | @REM Execute a user defined script before this one 45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 49 | :skipRcPre 50 | 51 | @setlocal 52 | 53 | set ERROR_CODE=0 54 | 55 | @REM To isolate internal variables from possible post scripts, we use another setlocal 56 | @setlocal 57 | 58 | @REM ==== START VALIDATION ==== 59 | if not "%JAVA_HOME%" == "" goto OkJHome 60 | 61 | echo. 62 | echo Error: JAVA_HOME not found in your environment. >&2 63 | echo Please set the JAVA_HOME variable in your environment to match the >&2 64 | echo location of your Java installation. >&2 65 | echo. 66 | goto error 67 | 68 | :OkJHome 69 | if exist "%JAVA_HOME%\bin\java.exe" goto init 70 | 71 | echo. 72 | echo Error: JAVA_HOME is set to an invalid directory. >&2 73 | echo JAVA_HOME = "%JAVA_HOME%" >&2 74 | echo Please set the JAVA_HOME variable in your environment to match the >&2 75 | echo location of your Java installation. >&2 76 | echo. 77 | goto error 78 | 79 | @REM ==== END VALIDATION ==== 80 | 81 | :init 82 | 83 | set MAVEN_CMD_LINE_ARGS=%* 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | 121 | set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar"" 122 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 123 | 124 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS% 125 | if ERRORLEVEL 1 goto error 126 | goto end 127 | 128 | :error 129 | set ERROR_CODE=1 130 | 131 | :end 132 | @endlocal & set ERROR_CODE=%ERROR_CODE% 133 | 134 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 135 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 136 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 137 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 138 | :skipRcPost 139 | 140 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 141 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 142 | 143 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 144 | 145 | exit /B %ERROR_CODE% -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-two-datasource/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | doma-spring-boot-sample-two-datasource 7 | jar 8 | 9 | doma-spring-boot-sample-two-datasource 10 | Demo project for Spring Boot 11 | 12 | 13 | org.seasar.doma.boot 14 | doma-spring-boot-samples 15 | 2.5.0-SNAPSHOT 16 | ../pom.xml 17 | 18 | 19 | 20 | 21 | org.seasar.doma 22 | doma-processor 23 | ${doma.version} 24 | true 25 | 26 | 27 | org.seasar.doma.boot 28 | doma-spring-boot-starter 29 | ${project.version} 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-configuration-processor 34 | true 35 | 36 | 37 | com.h2database 38 | h2 39 | runtime 40 | 41 | 42 | org.springframework.boot 43 | spring-boot-starter-test 44 | test 45 | 46 | 47 | 48 | 49 | 50 | 51 | org.springframework.boot 52 | spring-boot-maven-plugin 53 | ${spring-boot.version} 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-two-datasource/src/main/java/org/seasar/doma/boot/sample/Application.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class Application { 8 | 9 | @SuppressWarnings("resource") 10 | public static void main(String[] args) { 11 | SpringApplication.run(Application.class, args); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-two-datasource/src/main/java/org/seasar/doma/boot/sample/annotation/Secondary.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample.annotation; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | 7 | import org.springframework.beans.factory.annotation.Qualifier; 8 | 9 | @Qualifier("secondary") 10 | @Retention(RetentionPolicy.RUNTIME) 11 | @Documented 12 | public @interface Secondary { 13 | } 14 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-two-datasource/src/main/java/org/seasar/doma/boot/sample/annotation/SecondaryConfigAutowireable.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample.annotation; 2 | 3 | import org.seasar.doma.AnnotateWith; 4 | import org.seasar.doma.Annotation; 5 | import org.seasar.doma.AnnotationTarget; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Repository; 8 | 9 | @AnnotateWith(annotations = { 10 | @Annotation(target = AnnotationTarget.CLASS, type = Repository.class), 11 | @Annotation(target = AnnotationTarget.CONSTRUCTOR, type = Autowired.class), 12 | @Annotation(target = AnnotationTarget.CONSTRUCTOR_PARAMETER, type = Secondary.class), 13 | }) 14 | public @interface SecondaryConfigAutowireable { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-two-datasource/src/main/java/org/seasar/doma/boot/sample/configuration/DataSourceConfiguration.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample.configuration; 2 | 3 | import javax.sql.DataSource; 4 | 5 | import org.seasar.doma.boot.sample.annotation.Secondary; 6 | import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; 7 | import org.springframework.boot.autoconfigure.sql.init.SqlDataSourceScriptDatabaseInitializer; 8 | import org.springframework.boot.autoconfigure.sql.init.SqlInitializationProperties; 9 | import org.springframework.boot.context.properties.ConfigurationProperties; 10 | import org.springframework.context.annotation.Bean; 11 | import org.springframework.context.annotation.Configuration; 12 | import org.springframework.context.annotation.Primary; 13 | 14 | import com.zaxxer.hikari.HikariDataSource; 15 | 16 | @Configuration 17 | public class DataSourceConfiguration { 18 | 19 | @Primary 20 | @Bean 21 | @ConfigurationProperties(prefix = "spring.datasource") 22 | public DataSourceProperties dataSourceProperties() { 23 | return new DataSourceProperties(); 24 | } 25 | 26 | @Secondary 27 | @Bean 28 | @ConfigurationProperties(prefix = "secondary.datasource") 29 | public DataSourceProperties secondaryDataSourceProperties() { 30 | return new DataSourceProperties(); 31 | } 32 | 33 | @Primary 34 | @Bean 35 | @ConfigurationProperties(prefix = "spring.datasource.hikari") 36 | public HikariDataSource dataSource(DataSourceProperties properties) { 37 | return properties.initializeDataSourceBuilder().type(HikariDataSource.class).build(); 38 | } 39 | 40 | @Secondary 41 | @Bean 42 | @ConfigurationProperties(prefix = "secondary.datasource.hikari") 43 | public HikariDataSource secondaryDataSource(@Secondary DataSourceProperties properties) { 44 | return properties.initializeDataSourceBuilder().type(HikariDataSource.class).build(); 45 | } 46 | 47 | @Primary 48 | @Bean 49 | @ConfigurationProperties(prefix = "spring.sql.init") 50 | public SqlInitializationProperties sqlInitializationProperties() { 51 | return new SqlInitializationProperties(); 52 | } 53 | 54 | @Secondary 55 | @Bean 56 | @ConfigurationProperties(prefix = "secondary.sql.init") 57 | public SqlInitializationProperties secondarySqlInitializationProperties() { 58 | return new SqlInitializationProperties(); 59 | } 60 | 61 | @Primary 62 | @Bean 63 | public SqlDataSourceScriptDatabaseInitializer dataSourceInitializer(DataSource dataSource, 64 | SqlInitializationProperties properties) { 65 | return new SqlDataSourceScriptDatabaseInitializer(dataSource, properties); 66 | } 67 | 68 | @Secondary 69 | @Bean 70 | public SqlDataSourceScriptDatabaseInitializer secondaryDataSourceInitializer( 71 | @Secondary DataSource dataSource, 72 | @Secondary SqlInitializationProperties properties) { 73 | return new SqlDataSourceScriptDatabaseInitializer(dataSource, properties); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-two-datasource/src/main/java/org/seasar/doma/boot/sample/configuration/DomaConfiguration.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample.configuration; 2 | 3 | import javax.sql.DataSource; 4 | 5 | import org.seasar.doma.boot.autoconfigure.DomaConfigBuilder; 6 | import org.seasar.doma.boot.autoconfigure.DomaProperties; 7 | import org.seasar.doma.boot.sample.annotation.Secondary; 8 | import org.seasar.doma.jdbc.Config; 9 | import org.seasar.doma.jdbc.DuplicateColumnHandler; 10 | import org.seasar.doma.jdbc.EntityListenerProvider; 11 | import org.seasar.doma.jdbc.JdbcLogger; 12 | import org.seasar.doma.jdbc.ScriptFileLoader; 13 | import org.seasar.doma.jdbc.SqlBuilderSettings; 14 | import org.seasar.doma.jdbc.statistic.StatisticManager; 15 | import org.springframework.boot.context.properties.ConfigurationProperties; 16 | import org.springframework.context.annotation.Bean; 17 | import org.springframework.context.annotation.Configuration; 18 | import org.springframework.context.annotation.Primary; 19 | 20 | @Configuration 21 | public class DomaConfiguration { 22 | 23 | @Primary 24 | @Bean 25 | @ConfigurationProperties("doma") 26 | public DomaProperties domaProperties() { 27 | return new DomaProperties(); 28 | } 29 | 30 | @Secondary 31 | @Bean 32 | @ConfigurationProperties("secondary.doma") 33 | public DomaProperties secondaryDomaProperties() { 34 | return new DomaProperties(); 35 | } 36 | 37 | @Primary 38 | @Bean 39 | public DomaConfigBuilder domaConfigBuilder(DomaProperties properties) { 40 | return properties.initializeDomaConfigBuilder(); 41 | } 42 | 43 | @Secondary 44 | @Bean 45 | public DomaConfigBuilder secondaryDomaConfigBuilder(@Secondary DomaProperties properties) { 46 | return properties.initializeDomaConfigBuilder(); 47 | } 48 | 49 | @Primary 50 | @Bean 51 | public Config config(DomaConfigBuilder domaConfigBuilder, DataSource dataSource, 52 | JdbcLogger jdbcLogger, EntityListenerProvider entityListenerProvider, 53 | DuplicateColumnHandler duplicateColumnHandler, ScriptFileLoader scriptFileLoader, 54 | SqlBuilderSettings sqlBuilderSettings, StatisticManager statisticManager) { 55 | return domaConfigBuilder 56 | .dataSource(dataSource) 57 | .jdbcLogger(jdbcLogger) 58 | .entityListenerProvider(entityListenerProvider) 59 | .duplicateColumnHandler(duplicateColumnHandler) 60 | .scriptFileLoader(scriptFileLoader) 61 | .sqlBuilderSettings(sqlBuilderSettings) 62 | .statisticManager(statisticManager) 63 | .build(); 64 | } 65 | 66 | @Secondary 67 | @Bean 68 | public Config secondaryConfig(@Secondary DomaConfigBuilder domaConfigBuilder, 69 | @Secondary DataSource dataSource, JdbcLogger jdbcLogger, 70 | EntityListenerProvider entityListenerProvider, 71 | DuplicateColumnHandler duplicateColumnHandler, ScriptFileLoader scriptFileLoader, 72 | SqlBuilderSettings sqlBuilderSettings, StatisticManager statisticManager) { 73 | return domaConfigBuilder 74 | .dataSource(dataSource) 75 | .jdbcLogger(jdbcLogger) 76 | .entityListenerProvider(entityListenerProvider) 77 | .duplicateColumnHandler(duplicateColumnHandler) 78 | .scriptFileLoader(scriptFileLoader) 79 | .sqlBuilderSettings(sqlBuilderSettings) 80 | .statisticManager(statisticManager) 81 | .build(); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-two-datasource/src/main/java/org/seasar/doma/boot/sample/configuration/TransactionManagerConfiguration.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample.configuration; 2 | 3 | import javax.sql.DataSource; 4 | 5 | import org.seasar.doma.boot.sample.annotation.Secondary; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.jdbc.datasource.DataSourceTransactionManager; 9 | 10 | @Configuration 11 | public class TransactionManagerConfiguration { 12 | 13 | @Bean 14 | public DataSourceTransactionManager primaryTransactionManager(DataSource dataSource) { 15 | return new DataSourceTransactionManager(dataSource); 16 | } 17 | 18 | @Bean 19 | public DataSourceTransactionManager secondaryTransactionManager( 20 | @Secondary DataSource dataSource) { 21 | return new DataSourceTransactionManager(dataSource); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-two-datasource/src/main/java/org/seasar/doma/boot/sample/dao/PrimaryDao.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample.dao; 2 | 3 | import java.util.Optional; 4 | 5 | import org.seasar.doma.Dao; 6 | import org.seasar.doma.Insert; 7 | import org.seasar.doma.Select; 8 | import org.seasar.doma.boot.ConfigAutowireable; 9 | import org.seasar.doma.boot.sample.entity.PrimaryMessage; 10 | import org.seasar.doma.jdbc.Result; 11 | 12 | @Dao 13 | @ConfigAutowireable 14 | public interface PrimaryDao { 15 | 16 | @Select 17 | Optional selectById(Integer id); 18 | 19 | @Insert 20 | Result insert(PrimaryMessage message); 21 | } 22 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-two-datasource/src/main/java/org/seasar/doma/boot/sample/dao/SecondaryDao.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample.dao; 2 | 3 | import java.util.Optional; 4 | 5 | import org.seasar.doma.Dao; 6 | import org.seasar.doma.Insert; 7 | import org.seasar.doma.Select; 8 | import org.seasar.doma.boot.sample.annotation.SecondaryConfigAutowireable; 9 | import org.seasar.doma.boot.sample.entity.SecondaryMessage; 10 | import org.seasar.doma.jdbc.Result; 11 | 12 | @Dao 13 | @SecondaryConfigAutowireable 14 | public interface SecondaryDao { 15 | 16 | @Select 17 | Optional selectById(Integer id); 18 | 19 | @Insert 20 | Result insert(SecondaryMessage message); 21 | } 22 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-two-datasource/src/main/java/org/seasar/doma/boot/sample/entity/PrimaryMessage.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample.entity; 2 | 3 | import org.seasar.doma.Entity; 4 | import org.seasar.doma.Id; 5 | 6 | @Entity(immutable = true) 7 | public class PrimaryMessage { 8 | 9 | @Id 10 | public final Integer id; 11 | public final String content; 12 | 13 | public PrimaryMessage(Integer id, String content) { 14 | this.id = id; 15 | this.content = content; 16 | } 17 | 18 | @Override 19 | public String toString() { 20 | return id + ": " + content; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-two-datasource/src/main/java/org/seasar/doma/boot/sample/entity/SecondaryMessage.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample.entity; 2 | 3 | import org.seasar.doma.Entity; 4 | import org.seasar.doma.Id; 5 | 6 | @Entity(immutable = true) 7 | public class SecondaryMessage { 8 | 9 | @Id 10 | public final Integer id; 11 | public final String content; 12 | 13 | public SecondaryMessage(Integer id, String content) { 14 | this.id = id; 15 | this.content = content; 16 | } 17 | 18 | @Override 19 | public String toString() { 20 | return id + ": " + content; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-two-datasource/src/main/java/org/seasar/doma/boot/sample/service/SampleService.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample.service; 2 | 3 | import java.util.Optional; 4 | 5 | import org.seasar.doma.boot.sample.dao.PrimaryDao; 6 | import org.seasar.doma.boot.sample.dao.SecondaryDao; 7 | import org.seasar.doma.boot.sample.entity.PrimaryMessage; 8 | import org.seasar.doma.boot.sample.entity.SecondaryMessage; 9 | import org.springframework.stereotype.Service; 10 | import org.springframework.transaction.annotation.Transactional; 11 | 12 | @Service 13 | public class SampleService { 14 | 15 | private final PrimaryDao primaryDao; 16 | private final SecondaryDao secondaryDao; 17 | 18 | public SampleService(PrimaryDao primaryDao, SecondaryDao secondaryDao) { 19 | this.primaryDao = primaryDao; 20 | this.secondaryDao = secondaryDao; 21 | } 22 | 23 | public Optional primaryMessage(Integer id) { 24 | return primaryDao.selectById(id); 25 | } 26 | 27 | public Optional secondaryMessage(Integer id) { 28 | return secondaryDao.selectById(id); 29 | } 30 | 31 | @Transactional(transactionManager = "primaryTransactionManager") 32 | public void insertPrimary(PrimaryMessage message, boolean thrownException) { 33 | primaryDao.insert(message); 34 | if (thrownException) { 35 | throw new RuntimeException(); 36 | } 37 | } 38 | 39 | @Transactional(transactionManager = "secondaryTransactionManager") 40 | public void insertSecondary(SecondaryMessage message, boolean thrownException) { 41 | secondaryDao.insert(message); 42 | if (thrownException) { 43 | throw new RuntimeException(); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-two-datasource/src/main/resources/META-INF/org/seasar/doma/boot/sample/dao/PrimaryDao/selectById.sql: -------------------------------------------------------------------------------- 1 | select /*%expand*/* from primary_message 2 | where id = /*id*/0 3 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-two-datasource/src/main/resources/META-INF/org/seasar/doma/boot/sample/dao/SecondaryDao/selectById.sql: -------------------------------------------------------------------------------- 1 | select /*%expand*/* from secondary_message 2 | where id = /*id*/0 3 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-two-datasource/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | #logging.level.org.springframework.jdbc.datasource=debug 2 | #logging.level.com.zaxxer.hikari=debug 3 | 4 | spring.datasource.url=jdbc:h2:mem:primary;DB_CLOSE_DELAY=-1 5 | spring.sql.init.enabled=always 6 | #spring.datasource.hikari.max-lifetime=1800000 7 | #spring.datasource.hikari.maximum-pool-size=10 8 | #spring.datasource.hikari.minimum-idle=10 9 | doma.dialect=H2 10 | doma.naming=SNAKE_LOWER_CASE 11 | 12 | secondary.datasource.url=jdbc:h2:mem:secondary;DB_CLOSE_DELAY=-1 13 | secondary.sql.init.schema-locations=classpath:secondary-schema.sql 14 | secondary.sql.init.data-locations=classpath:secondary-data.sql 15 | secondary.sql.init.enabled=always 16 | #secondary.datasource.hikari.max-lifetime=1800000 17 | #secondary.datasource.hikari.maximum-pool-size=10 18 | #secondary.datasource.hikari.minimum-idle=10 19 | secondary.doma.dialect=H2 20 | secondary.doma.naming=SNAKE_LOWER_CASE 21 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-two-datasource/src/main/resources/data.sql: -------------------------------------------------------------------------------- 1 | insert into primary_message (id, content) values (1, 'primary message'); -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-two-datasource/src/main/resources/schema.sql: -------------------------------------------------------------------------------- 1 | create table primary_message ( 2 | id int primary key, 3 | content varchar(100) 4 | ); -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-two-datasource/src/main/resources/secondary-data.sql: -------------------------------------------------------------------------------- 1 | insert into secondary_message (id, content) values (2, 'secondary message'); -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-two-datasource/src/main/resources/secondary-schema.sql: -------------------------------------------------------------------------------- 1 | create table secondary_message ( 2 | id int primary key, 3 | content varchar(100) 4 | ); -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-two-datasource/src/test/java/org/seasar/doma/boot/sample/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | 5 | import org.junit.jupiter.api.Test; 6 | import org.seasar.doma.boot.sample.entity.PrimaryMessage; 7 | import org.seasar.doma.boot.sample.entity.SecondaryMessage; 8 | import org.seasar.doma.boot.sample.service.SampleService; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.boot.test.context.SpringBootTest; 11 | 12 | @SpringBootTest 13 | class ApplicationTest { 14 | 15 | @Autowired 16 | private SampleService service; 17 | 18 | @Test 19 | void primary() { 20 | PrimaryMessage message = service.primaryMessage(1).orElseGet(() -> fail()); 21 | assertEquals(1, message.id); 22 | assertEquals("primary message", message.content); 23 | } 24 | 25 | @Test 26 | void secondary() { 27 | SecondaryMessage message = service.secondaryMessage(2).orElseGet(() -> fail()); 28 | assertEquals(2, message.id); 29 | assertEquals("secondary message", message.content); 30 | } 31 | 32 | @Test 33 | void commitPrimary() { 34 | { 35 | PrimaryMessage message = new PrimaryMessage(10, "primary commit"); 36 | 37 | boolean thrownException = false; 38 | 39 | service.insertPrimary(message, thrownException); 40 | } 41 | { 42 | PrimaryMessage message = service.primaryMessage(10).orElseGet(() -> fail()); 43 | assertEquals(10, message.id); 44 | assertEquals("primary commit", message.content); 45 | } 46 | } 47 | 48 | @Test 49 | void rollbackPrimary() { 50 | { 51 | PrimaryMessage message = new PrimaryMessage(100, "primary rollback"); 52 | 53 | boolean thrownException = true; 54 | 55 | assertThrows(RuntimeException.class, 56 | () -> service.insertPrimary(message, thrownException)); 57 | } 58 | 59 | assertFalse(service.primaryMessage(100).isPresent()); 60 | } 61 | 62 | @Test 63 | void commitSecondary() { 64 | { 65 | SecondaryMessage message = new SecondaryMessage(20, "secondary commit"); 66 | 67 | boolean thrownException = false; 68 | 69 | service.insertSecondary(message, thrownException); 70 | } 71 | { 72 | SecondaryMessage message = service.secondaryMessage(20).orElseGet(() -> fail()); 73 | assertEquals(20, message.id); 74 | assertEquals("secondary commit", message.content); 75 | } 76 | } 77 | 78 | @Test 79 | void rollbackSecondary() { 80 | { 81 | SecondaryMessage message = new SecondaryMessage(200, "secondary rollback"); 82 | 83 | boolean thrownException = true; 84 | 85 | assertThrows(RuntimeException.class, 86 | () -> service.insertSecondary(message, thrownException)); 87 | } 88 | 89 | assertFalse(service.secondaryMessage(200).isPresent()); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-unified-criteria/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/domaframework/doma-spring-boot/3d75478c299a8b4b55579f23245b2c387b3631ce/doma-spring-boot-samples/doma-spring-boot-sample-unified-criteria/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-unified-criteria/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.9.10/apache-maven-3.9.10-bin.zip -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-unified-criteria/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 40 | 41 | @REM set %HOME% to equivalent of $HOME 42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 43 | 44 | @REM Execute a user defined script before this one 45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 49 | :skipRcPre 50 | 51 | @setlocal 52 | 53 | set ERROR_CODE=0 54 | 55 | @REM To isolate internal variables from possible post scripts, we use another setlocal 56 | @setlocal 57 | 58 | @REM ==== START VALIDATION ==== 59 | if not "%JAVA_HOME%" == "" goto OkJHome 60 | 61 | echo. 62 | echo Error: JAVA_HOME not found in your environment. >&2 63 | echo Please set the JAVA_HOME variable in your environment to match the >&2 64 | echo location of your Java installation. >&2 65 | echo. 66 | goto error 67 | 68 | :OkJHome 69 | if exist "%JAVA_HOME%\bin\java.exe" goto init 70 | 71 | echo. 72 | echo Error: JAVA_HOME is set to an invalid directory. >&2 73 | echo JAVA_HOME = "%JAVA_HOME%" >&2 74 | echo Please set the JAVA_HOME variable in your environment to match the >&2 75 | echo location of your Java installation. >&2 76 | echo. 77 | goto error 78 | 79 | @REM ==== END VALIDATION ==== 80 | 81 | :init 82 | 83 | set MAVEN_CMD_LINE_ARGS=%* 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | 121 | set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar"" 122 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 123 | 124 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS% 125 | if ERRORLEVEL 1 goto error 126 | goto end 127 | 128 | :error 129 | set ERROR_CODE=1 130 | 131 | :end 132 | @endlocal & set ERROR_CODE=%ERROR_CODE% 133 | 134 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 135 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 136 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 137 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 138 | :skipRcPost 139 | 140 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 141 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 142 | 143 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 144 | 145 | exit /B %ERROR_CODE% -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-unified-criteria/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | doma-spring-boot-sample-unified-criteria 7 | jar 8 | 9 | doma-spring-boot-sample-unified-criteria 10 | Sample using Unified Criteria API 11 | 12 | 13 | org.seasar.doma.boot 14 | doma-spring-boot-samples 15 | 2.5.0-SNAPSHOT 16 | ../pom.xml 17 | 18 | 19 | 20 | 21 | org.seasar.doma.boot 22 | doma-spring-boot-starter 23 | ${project.version} 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-web 28 | 29 | 30 | com.h2database 31 | h2 32 | runtime 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-starter-test 37 | test 38 | 39 | 40 | 41 | 42 | 43 | 44 | org.springframework.boot 45 | spring-boot-maven-plugin 46 | ${spring-boot.version} 47 | 48 | 49 | org.apache.maven.plugins 50 | maven-compiler-plugin 51 | 52 | 53 | 54 | org.seasar.doma 55 | doma-processor 56 | ${doma.version} 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-unified-criteria/src/main/java/org/seasar/doma/boot/sample/Application.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class Application { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(Application.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-unified-criteria/src/main/java/org/seasar/doma/boot/sample/Message.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import org.seasar.doma.*; 4 | 5 | @Entity(metamodel = @Metamodel) 6 | @Table(name = "messages") 7 | public record Message( 8 | @Id @GeneratedValue(strategy = GenerationType.IDENTITY) Integer id, 9 | String text) { 10 | } 11 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-unified-criteria/src/main/java/org/seasar/doma/boot/sample/MessageController.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import java.util.List; 4 | 5 | import org.seasar.doma.boot.UnifiedCriteriaPageable; 6 | import org.seasar.doma.jdbc.criteria.QueryDsl; 7 | import org.springframework.data.domain.Pageable; 8 | import org.springframework.data.web.PageableDefault; 9 | import org.springframework.web.bind.annotation.GetMapping; 10 | import org.springframework.web.bind.annotation.PostMapping; 11 | import org.springframework.web.bind.annotation.RequestBody; 12 | import org.springframework.web.bind.annotation.RequestMapping; 13 | import org.springframework.web.bind.annotation.RestController; 14 | 15 | @RestController 16 | @RequestMapping("/") 17 | public class MessageController { 18 | 19 | private final QueryDsl queryDsl; 20 | 21 | public MessageController(QueryDsl queryDsl) { 22 | this.queryDsl = queryDsl; 23 | } 24 | 25 | @GetMapping 26 | List list(@PageableDefault(page = 0, size = 3, sort = "id,asc") Pageable pageable) { 27 | var m = new Message_(); 28 | var p = UnifiedCriteriaPageable.from(pageable, m); 29 | return queryDsl.from(m) 30 | .offset(p.offset()) 31 | .limit(p.limit()) 32 | .orderBy(p.orderBy()) 33 | .fetch(); 34 | } 35 | 36 | @PostMapping("add") 37 | Message add(@RequestBody Message message) { 38 | var m = new Message_(); 39 | var result = queryDsl.insert(m).single(message).execute(); 40 | return result.getEntity(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-unified-criteria/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | doma.dialect=H2 2 | logging.level.org.springframework.jdbc.datasource.DataSourceTransactionManager=DEBUG -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-unified-criteria/src/main/resources/schema.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS messages ( 2 | id INT PRIMARY KEY AUTO_INCREMENT, 3 | text VARCHAR(255) 4 | ); 5 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/doma-spring-boot-sample-unified-criteria/src/test/java/org/seasar/doma/boot/sample/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package org.seasar.doma.boot.sample; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | import org.junit.jupiter.api.BeforeEach; 9 | import org.junit.jupiter.api.Test; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.boot.test.context.SpringBootTest; 12 | import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; 13 | import org.springframework.boot.test.web.server.LocalServerPort; 14 | import org.springframework.core.ParameterizedTypeReference; 15 | import org.springframework.web.client.RestClient; 16 | 17 | @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) 18 | class ApplicationTest { 19 | private RestClient http; 20 | private final ParameterizedTypeReference> typedReference = new ParameterizedTypeReference>() { 21 | }; 22 | @LocalServerPort 23 | private int port; 24 | 25 | @BeforeEach 26 | void setUp(@Autowired RestClient.Builder builder) { 27 | http = builder.baseUrl("http://localhost:" + port).build(); 28 | } 29 | 30 | @Test 31 | void test() { 32 | for (var i = 0; i < 10; i++) { 33 | var text = "message%d".formatted(i); 34 | http.post().uri("/add").body(Map.of("text", text)).retrieve().body(Message.class); 35 | } 36 | 37 | { 38 | List messages = http.get() 39 | .retrieve() 40 | .body(typedReference); 41 | assertEquals(3, messages.size()); 42 | assertEquals("message0", messages.get(0).text()); 43 | assertEquals("message1", messages.get(1).text()); 44 | assertEquals("message2", messages.get(2).text()); 45 | } 46 | 47 | { 48 | List messages = http.get() 49 | .uri(builder -> builder.queryParam("page", 3).queryParam("size", 2) 50 | .queryParam("sort", "id,desc").build()) 51 | .retrieve().body(typedReference); 52 | assertEquals(2, messages.size()); 53 | assertEquals("message3", messages.get(0).text()); 54 | assertEquals("message2", messages.get(1).text()); 55 | } 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /doma-spring-boot-samples/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | doma-spring-boot 7 | org.seasar.doma.boot 8 | 2.5.0-SNAPSHOT 9 | 10 | pom 11 | 4.0.0 12 | Doma Samples 13 | 14 | doma-spring-boot-samples 15 | doma-spring-boot-samples 16 | 17 | 18 | doma-spring-boot-sample-simple 19 | doma-spring-boot-sample-entity-listener 20 | doma-spring-boot-sample-event-handler 21 | doma-spring-boot-sample-two-datasource 22 | doma-spring-boot-sample-unified-criteria 23 | doma-spring-boot-sample-docker-compose 24 | doma-spring-boot-sample-testcontainers 25 | 26 | 27 | 28 | true 29 | 30 | 31 | 32 | 33 | backward-compatible 34 | 35 | 36 | 37 | org.apache.maven.plugins 38 | maven-compiler-plugin 39 | 40 | 41 | -Adoma.version.validation=false 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /doma-spring-boot-starter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | doma-spring-boot-starter 7 | jar 8 | 9 | doma-spring-boot-starter 10 | Spring Boot Starter project for Doma 11 | 12 | 13 | org.seasar.doma.boot 14 | doma-spring-boot 15 | 2.5.0-SNAPSHOT 16 | ../pom.xml 17 | 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter 23 | 24 | 25 | org.springframework.boot 26 | spring-boot-starter-jdbc 27 | 28 | 29 | org.seasar.doma.boot 30 | doma-spring-boot-autoconfigure 31 | ${project.version} 32 | 33 | 34 | 35 | 36 | 37 | 38 | org.apache.maven.plugins 39 | maven-jar-plugin 40 | 41 | 42 | 43 | doma.spring.boot.starter 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /doma-spring-boot-starter/src/main/resources/META-INF/spring.provides: -------------------------------------------------------------------------------- 1 | provides: doma-spring-boot-autoconfigure -------------------------------------------------------------------------------- /how-to-release.md: -------------------------------------------------------------------------------- 1 | # How to release 2 | 3 | ## Create release branch 4 | 5 | Switch to a new branch to work on the release. 6 | 7 | ``` 8 | git switch -c release-x.y.z 9 | ``` 10 | 11 | ## Update README 12 | 13 | Update the version described in the README. 14 | 15 | The following example shows the command to update the description from 1.3.0 to 1.4.0. 16 | 17 | ``` 18 | sed -i '' -e 's/1\.3\.0/1\.4\.0/g' README.md 19 | ``` 20 | 21 | And change `doma-processor` version. 22 | 23 | ## Set a new version 24 | 25 | Update pom.xml by Maven Versions Plugin. 26 | 27 | ``` 28 | ./mvnw versions:set -DnewVersion=x.y.z 29 | ``` 30 | 31 | Run all tests. 32 | 33 | ``` 34 | ./mvnw test 35 | ``` 36 | 37 | Commit the new version. 38 | 39 | ``` 40 | ./mvnw versions:commit 41 | ``` 42 | 43 | ## Push changes to GitHub 44 | 45 | Do `git commit` changes to the README and pom.xml. 46 | 47 | ``` 48 | git add . 49 | git commit -m "Release x.y.z" 50 | ``` 51 | 52 | And do `git push` to GitHub. 53 | 54 | ``` 55 | git push origin release-x.y.z 56 | ``` 57 | 58 | ## Do release work on GitHub 59 | 60 | Create a new PR from release branch and merge it into the master branch. 61 | 62 | The CI job running after the merge releases a new version artifact to the Maven Central Repository. 63 | 64 | Check https://repo.maven.apache.org/maven2/org/seasar/doma/boot/doma-spring-boot/ . 65 | 66 | 67 | ## Update doma-spring-boot-demo 68 | 69 | Update pom.xml of [doma-spring-boot-demo](https://github.com/backpaper0/doma-spring-boot-demo) to set a new version of doma-spring-boot. 70 | 71 | Note: doma-spring-boot-demo is a personal repository for backpaper0. 72 | 73 | ## Prepare a next SNAPSHOT version 74 | 75 | First, pull the master branch. 76 | 77 | ``` 78 | git switch master 79 | git pull 80 | ``` 81 | 82 | Set a next SNAPSHOT version to pom.xml and commit. 83 | 84 | ``` 85 | ./mvnw versions:set -DnewVersion=x.z.z-SNAPSHOT 86 | ./mvnw versions:commit 87 | ``` 88 | 89 | Do `git commit` and push to GitHub. 90 | 91 | ``` 92 | git add . 93 | git commit -m "Prepare a next SNAPSHOT version" 94 | git push origin master 95 | ``` 96 | 97 | -------------------------------------------------------------------------------- /mvnw.cmd: -------------------------------------------------------------------------------- 1 | <# : batch portion 2 | @REM ---------------------------------------------------------------------------- 3 | @REM Licensed to the Apache Software Foundation (ASF) under one 4 | @REM or more contributor license agreements. See the NOTICE file 5 | @REM distributed with this work for additional information 6 | @REM regarding copyright ownership. The ASF licenses this file 7 | @REM to you under the Apache License, Version 2.0 (the 8 | @REM "License"); you may not use this file except in compliance 9 | @REM with the License. You may obtain a copy of the License at 10 | @REM 11 | @REM http://www.apache.org/licenses/LICENSE-2.0 12 | @REM 13 | @REM Unless required by applicable law or agreed to in writing, 14 | @REM software distributed under the License is distributed on an 15 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | @REM KIND, either express or implied. See the License for the 17 | @REM specific language governing permissions and limitations 18 | @REM under the License. 19 | @REM ---------------------------------------------------------------------------- 20 | 21 | @REM ---------------------------------------------------------------------------- 22 | @REM Apache Maven Wrapper startup batch script, version 3.3.0 23 | @REM 24 | @REM Optional ENV vars 25 | @REM MVNW_REPOURL - repo url base for downloading maven distribution 26 | @REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven 27 | @REM MVNW_VERBOSE - true: enable verbose log; others: silence the output 28 | @REM ---------------------------------------------------------------------------- 29 | 30 | @IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) 31 | @SET __MVNW_CMD__= 32 | @SET __MVNW_ERROR__= 33 | @SET __MVNW_PSMODULEP_SAVE=%PSModulePath% 34 | @SET PSModulePath= 35 | @FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( 36 | IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) 37 | ) 38 | @SET PSModulePath=%__MVNW_PSMODULEP_SAVE% 39 | @SET __MVNW_PSMODULEP_SAVE= 40 | @SET __MVNW_ARG0_NAME__= 41 | @SET MVNW_USERNAME= 42 | @SET MVNW_PASSWORD= 43 | @IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) 44 | @echo Cannot start maven from wrapper >&2 && exit /b 1 45 | @GOTO :EOF 46 | : end batch / begin powershell #> 47 | 48 | $ErrorActionPreference = "Stop" 49 | if ($env:MVNW_VERBOSE -eq "true") { 50 | $VerbosePreference = "Continue" 51 | } 52 | 53 | # calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties 54 | $distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl 55 | if (!$distributionUrl) { 56 | Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" 57 | } 58 | 59 | switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { 60 | "maven-mvnd-*" { 61 | $USE_MVND = $true 62 | $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" 63 | $MVN_CMD = "mvnd.cmd" 64 | break 65 | } 66 | default { 67 | $USE_MVND = $false 68 | $MVN_CMD = $script -replace '^mvnw','mvn' 69 | break 70 | } 71 | } 72 | 73 | # apply MVNW_REPOURL and calculate MAVEN_HOME 74 | # maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ 75 | if ($env:MVNW_REPOURL) { 76 | $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } 77 | $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" 78 | } 79 | $distributionUrlName = $distributionUrl -replace '^.*/','' 80 | $distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' 81 | $MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" 82 | $MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' 83 | $MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" 84 | 85 | if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { 86 | Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" 87 | Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" 88 | exit $? 89 | } 90 | 91 | if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { 92 | Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" 93 | } 94 | 95 | # prepare tmp dir 96 | $TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile 97 | $TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" 98 | $TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null 99 | trap { 100 | if ($TMP_DOWNLOAD_DIR.Exists) { 101 | try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } 102 | catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } 103 | } 104 | } 105 | 106 | New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null 107 | 108 | # Download and Install Apache Maven 109 | Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." 110 | Write-Verbose "Downloading from: $distributionUrl" 111 | Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" 112 | 113 | $webclient = New-Object System.Net.WebClient 114 | if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { 115 | $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) 116 | } 117 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 118 | $webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null 119 | 120 | # If specified, validate the SHA-256 sum of the Maven distribution zip file 121 | $distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum 122 | if ($distributionSha256Sum) { 123 | if ($USE_MVND) { 124 | Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." 125 | } 126 | Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash 127 | if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { 128 | Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." 129 | } 130 | } 131 | 132 | # unzip and move 133 | Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null 134 | Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null 135 | try { 136 | Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null 137 | } catch { 138 | if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { 139 | Write-Error "fail to move MAVEN_HOME" 140 | } 141 | } finally { 142 | try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } 143 | catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } 144 | } 145 | 146 | Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" 147 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "local>domaframework/renovate-config" 5 | ], 6 | "ignoreDeps": [ 7 | "org.springframework.boot:spring-boot-dependencies", 8 | "org.springframework.boot:spring-boot-maven-plugin" 9 | ] 10 | } 11 | --------------------------------------------------------------------------------