diff --git a/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/config/ApplicationProperties.java b/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/config/ApplicationProperties.java index 0a01f04d1..8955d6391 100644 --- a/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/config/ApplicationProperties.java +++ b/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/config/ApplicationProperties.java @@ -2,11 +2,13 @@ import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.NestedConfigurationProperty; @Data @ConfigurationProperties("application") public class ApplicationProperties { - private Cors cors = new Cors(); + + @NestedConfigurationProperty private Cors cors = new Cors(); @Data public static class Cors { diff --git a/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/config/JooqConfiguration.java b/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/config/JooqConfiguration.java index 2a79dccdc..1169880b3 100644 --- a/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/config/JooqConfiguration.java +++ b/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/config/JooqConfiguration.java @@ -8,13 +8,20 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; +import org.springframework.data.domain.ReactiveAuditorAware; import org.springframework.data.r2dbc.config.EnableR2dbcAuditing; import org.springframework.r2dbc.connection.TransactionAwareConnectionFactoryProxy; +import reactor.core.publisher.Mono; -@Configuration -@EnableR2dbcAuditing +@Configuration(proxyBeanMethods = false) +@EnableR2dbcAuditing(auditorAwareRef = "myAuditorProvider", modifyOnCreate = false) public class JooqConfiguration { + @Bean + public ReactiveAuditorAware myAuditorProvider() { + return () -> Mono.justOrEmpty("appUser"); + } + @Bean DSLContext dslContext(ConnectionFactory connectionFactory) { return DSL.using(new TransactionAwareConnectionFactoryProxy(connectionFactory)).dsl(); diff --git a/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/entities/PostTagRelation.java b/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/entities/PostTagRelation.java index 86f3ef292..b8f834154 100644 --- a/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/entities/PostTagRelation.java +++ b/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/entities/PostTagRelation.java @@ -1,21 +1,11 @@ package com.example.jooq.r2dbc.entities; +import java.util.Objects; import java.util.UUID; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import lombok.ToString; +import org.apache.commons.lang3.builder.ToStringBuilder; import org.springframework.data.relational.core.mapping.Column; import org.springframework.data.relational.core.mapping.Table; -@Getter -@Setter -@ToString -@Builder -@NoArgsConstructor -@AllArgsConstructor @Table(value = "posts_tags") public class PostTagRelation { @@ -24,4 +14,47 @@ public class PostTagRelation { @Column("tag_id") private UUID tagId; + + public PostTagRelation() {} + + public PostTagRelation(UUID postId, UUID tagId) { + this.postId = postId; + this.tagId = tagId; + } + + public UUID getPostId() { + return postId; + } + + public PostTagRelation setPostId(UUID postId) { + this.postId = postId; + return this; + } + + public UUID getTagId() { + return tagId; + } + + public PostTagRelation setTagId(UUID tagId) { + this.tagId = tagId; + return this; + } + + @Override + public String toString() { + return new ToStringBuilder(this).append("postId", postId).append("tagId", tagId).toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof PostTagRelation)) return false; + PostTagRelation that = (PostTagRelation) o; + return Objects.equals(postId, that.postId) && Objects.equals(tagId, that.tagId); + } + + @Override + public int hashCode() { + return Objects.hash(postId, tagId); + } } diff --git a/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/entities/Tags.java b/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/entities/Tags.java index 6132faa66..1abe7d7a3 100644 --- a/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/entities/Tags.java +++ b/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/entities/Tags.java @@ -1,22 +1,12 @@ package com.example.jooq.r2dbc.entities; +import java.util.Objects; import java.util.UUID; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import lombok.ToString; +import org.apache.commons.lang3.builder.ToStringBuilder; import org.springframework.data.annotation.Id; import org.springframework.data.relational.core.mapping.Column; import org.springframework.data.relational.core.mapping.Table; -@Getter -@Setter -@ToString -@Builder -@NoArgsConstructor -@AllArgsConstructor @Table(value = "tags") public class Tags { @@ -27,7 +17,41 @@ public class Tags { @Column("name") private String name; - public Tags(String name) { + public Tags() {} + + public UUID getId() { + return id; + } + + public Tags setId(UUID id) { + this.id = id; + return this; + } + + public String getName() { + return name; + } + + public Tags setName(String name) { this.name = name; + return this; + } + + @Override + public String toString() { + return new ToStringBuilder(this).append("id", id).append("name", name).toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Tags)) return false; + Tags tags = (Tags) o; + return Objects.equals(name, tags.name); + } + + @Override + public int hashCode() { + return Objects.hash(name); } } diff --git a/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/handler/PostHandler.java b/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/handler/PostHandler.java index 7842541a0..1babbfd29 100644 --- a/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/handler/PostHandler.java +++ b/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/handler/PostHandler.java @@ -12,7 +12,6 @@ import com.example.jooq.r2dbc.service.PostService; import com.example.jooq.r2dbc.utils.AppConstants; import java.net.URI; -import lombok.RequiredArgsConstructor; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; @@ -22,10 +21,14 @@ import reactor.core.publisher.Mono; @Component -@RequiredArgsConstructor public class PostHandler { + private final PostService postService; + public PostHandler(PostService postService) { + this.postService = postService; + } + @Loggable public Mono getAll(ServerRequest req) { return ok().body(this.postService.findAll(), PostSummary.class); diff --git a/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/handler/TagHandler.java b/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/handler/TagHandler.java index 9c45388f1..088b07000 100644 --- a/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/handler/TagHandler.java +++ b/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/handler/TagHandler.java @@ -10,7 +10,6 @@ import com.example.jooq.r2dbc.service.TagService; import com.example.jooq.r2dbc.utils.AppConstants; import java.net.URI; -import lombok.RequiredArgsConstructor; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; @@ -20,32 +19,35 @@ import reactor.core.publisher.Mono; @Component -@RequiredArgsConstructor @Loggable public class TagHandler { // Service responsible for handling Tag-related business logic private final TagService tagService; + public TagHandler(TagService tagService) { + this.tagService = tagService; + } + // Retrieve all tags based on query parameters for sorting and pagination public Mono getAll(ServerRequest req) { // Extracting and setting sort direction and field from query parameters - String sortDir = req.queryParam("sortDir").orElse(AppConstants.DEFAULT_SORT_DIRECTION); String sortBy = req.queryParam("sortBy").orElse(AppConstants.DEFAULT_SORT_BY); + String sortDir = req.queryParam("sortDir").orElse(AppConstants.DEFAULT_SORT_DIRECTION); Sort sort = sortDir.equalsIgnoreCase(Sort.Direction.ASC.name()) ? Sort.by(sortBy).ascending() : Sort.by(sortBy).descending(); // Creating Pageable instance for pagination - int pageNo = - req.queryParam("pageNo") - .map(Integer::parseInt) - .orElse(AppConstants.DEFAULT_PAGE_NUMBER); int pageSize = req.queryParam("pageSize") .map(Integer::parseInt) .orElse(AppConstants.DEFAULT_PAGE_SIZE); + int pageNo = + req.queryParam("pageNo") + .map(Integer::parseInt) + .orElse(AppConstants.DEFAULT_PAGE_NUMBER); Pageable pageable = PageRequest.of(pageNo, pageSize, sort); // Returning paginated result of tags diff --git a/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/repository/custom/impl/CustomPostRepositoryImpl.java b/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/repository/custom/impl/CustomPostRepositoryImpl.java index 04d596a23..3ead0fdd5 100644 --- a/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/repository/custom/impl/CustomPostRepositoryImpl.java +++ b/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/repository/custom/impl/CustomPostRepositoryImpl.java @@ -1,19 +1,21 @@ package com.example.jooq.r2dbc.repository.custom.impl; -import static com.example.jooq.r2dbc.testcontainersflyway.db.Tables.*; import static com.example.jooq.r2dbc.testcontainersflyway.db.Tables.POSTS; +import static com.example.jooq.r2dbc.testcontainersflyway.db.Tables.POSTS_TAGS; +import static com.example.jooq.r2dbc.testcontainersflyway.db.Tables.POST_COMMENTS; +import static com.example.jooq.r2dbc.testcontainersflyway.db.Tables.TAGS; import static org.jooq.impl.DSL.multiset; import static org.jooq.impl.DSL.select; import com.example.jooq.r2dbc.model.response.PostCommentResponse; import com.example.jooq.r2dbc.model.response.PostResponse; import com.example.jooq.r2dbc.repository.custom.CustomPostRepository; -import com.example.jooq.r2dbc.testcontainersflyway.db.tables.PostComments; -import com.example.jooq.r2dbc.testcontainersflyway.db.tables.Posts; import org.jooq.Condition; import org.jooq.DSLContext; import org.jooq.Record1; import org.jooq.impl.DSL; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; @@ -23,6 +25,7 @@ public class CustomPostRepositoryImpl extends JooqSorting implements CustomPostRepository { + private static final Logger log = LoggerFactory.getLogger(CustomPostRepositoryImpl.class); private final DSLContext dslContext; public CustomPostRepositoryImpl(DSLContext dslContext) { @@ -31,30 +34,42 @@ public CustomPostRepositoryImpl(DSLContext dslContext) { @Override public Mono> findByKeyword(String keyword, Pageable pageable) { - Condition where = DSL.trueCondition(); + log.debug("Searching posts with keyword: {}, pageable: {}", keyword, pageable); + // Build the where condition dynamically + Condition condition = DSL.trueCondition(); if (StringUtils.hasText(keyword)) { - where = where.and(POSTS.TITLE.likeIgnoreCase("%" + keyword + "%")); + condition = + condition.and( + DSL.or( + POSTS.TITLE.likeIgnoreCase( + DSL.concat( + DSL.val("%"), DSL.val(keyword), DSL.val("%"))), + POSTS.CONTENT.likeIgnoreCase( + DSL.concat( + DSL.val("%"), + DSL.val(keyword), + DSL.val("%"))))); } - var dataSql = + + // Construct the main data SQL query + var dataQuery = dslContext - .select( + .selectDistinct( POSTS.ID, POSTS.TITLE, POSTS.CONTENT, + // Fetch comments as a multiset multiset( select( - PostComments.POST_COMMENTS.ID, - PostComments.POST_COMMENTS.CONTENT, - PostComments.POST_COMMENTS - .CREATED_AT) - .from(PostComments.POST_COMMENTS) - .where( - PostComments.POST_COMMENTS.POST_ID - .eq(Posts.POSTS.ID))) + POST_COMMENTS.ID, + POST_COMMENTS.CONTENT, + POST_COMMENTS.CREATED_AT) + .from(POST_COMMENTS) + .where(POST_COMMENTS.POST_ID.eq(POSTS.ID))) .as("comments") .convertFrom( - record3s -> - record3s.into(PostCommentResponse.class)), + records -> records.into(PostCommentResponse.class)), + // Fetch tags as a multiset multiset( select(TAGS.NAME) .from(TAGS) @@ -62,28 +77,36 @@ public Mono> findByKeyword(String keyword, Pageable pageable) .on(TAGS.ID.eq(POSTS_TAGS.TAG_ID)) .where(POSTS_TAGS.POST_ID.eq(POSTS.ID))) .as("tags") - .convertFrom(record -> record.map(Record1::value1))) - .from(POSTS.leftJoin(POST_COMMENTS).on(POST_COMMENTS.POST_ID.eq(POSTS.ID))) - .where(where) - .groupBy(POSTS.ID) + .convertFrom(records -> records.map(Record1::value1))) + .from(POSTS) + .where(condition) .orderBy(getSortFields(pageable.getSort(), POSTS)) .limit(pageable.getPageSize()) .offset(pageable.getOffset()); - var countSql = dslContext.selectCount().from(POSTS).where(where); + // Construct the count query + var countQuery = dslContext.selectCount().from(POSTS).where(condition); + // Execute queries reactively and build the result page return Mono.zip( - Flux.from(dataSql) + Flux.from(dataQuery) .map( - r -> + record -> new PostResponse( - r.value1(), - r.value2(), - r.value3(), - r.value4(), - r.value5())) + record.value1(), // Post ID + record.value2(), // Post Title + record.value3(), // Post Content + record.value4(), // Comments + record.value5() // Tags + )) + .doOnError( + e -> + log.error( + "Error executing data query: {}", + e.getMessage())) .collectList(), - Mono.from(countSql).map(Record1::value1)) - .map(it -> new PageImpl<>(it.getT1(), pageable, it.getT2())); + Mono.from(countQuery).map(Record1::value1)) + .doOnError(e -> log.error("Error executing count query: {}", e.getMessage())) + .map(tuple -> new PageImpl<>(tuple.getT1(), pageable, tuple.getT2())); } } diff --git a/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/repository/custom/impl/CustomTagRepositoryImpl.java b/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/repository/custom/impl/CustomTagRepositoryImpl.java index d5f661245..c10f5ed50 100644 --- a/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/repository/custom/impl/CustomTagRepositoryImpl.java +++ b/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/repository/custom/impl/CustomTagRepositoryImpl.java @@ -4,7 +4,8 @@ import com.example.jooq.r2dbc.entities.Tags; import com.example.jooq.r2dbc.repository.custom.CustomTagRepository; -import org.jooq.*; +import org.jooq.DSLContext; +import org.jooq.Record1; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; @@ -30,8 +31,10 @@ public Mono> findAll(Pageable pageable) { .offset(pageable.getOffset()); var countSql = dslContext.selectCount().from(TAGS); return Mono.zip( - Flux.from(dataSql).map(r -> new Tags(r.value1(), r.value2())).collectList(), + Flux.from(dataSql) + .map(r -> new Tags().setId(r.value1()).setName(r.value2())) + .collectList(), Mono.from(countSql).map(Record1::value1)) - .map(it -> new PageImpl<>(it.getT1(), pageable, it.getT2())); + .map(tuple -> new PageImpl<>(tuple.getT1(), pageable, tuple.getT2())); } } diff --git a/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/repository/custom/impl/JooqSorting.java b/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/repository/custom/impl/JooqSorting.java index ad38ee98c..45c9ec6fe 100644 --- a/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/repository/custom/impl/JooqSorting.java +++ b/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/repository/custom/impl/JooqSorting.java @@ -11,10 +11,11 @@ public class JooqSorting { + /** Converts Spring Data Sort to jOOQ SortField. */ List> getSortFields(Sort sortSpecification, T tableType) { List> querySortFields = new ArrayList<>(); - if (sortSpecification == null) { + if (sortSpecification == null || !sortSpecification.iterator().hasNext()) { return querySortFields; } @@ -22,33 +23,31 @@ List> getSortFields(Sort sortSpecification, T tableType) { String sortFieldName = specifiedField.getProperty(); Sort.Direction sortDirection = specifiedField.getDirection(); - TableField tableField = getTableField(sortFieldName, tableType); - SortField querySortField = convertTableFieldToSortField(tableField, sortDirection); - querySortFields.add(querySortField); + TableField tableField = getTableField(sortFieldName, tableType); + if (tableField != null) { + querySortFields.add(convertTableFieldToSortField(tableField, sortDirection)); + } } return querySortFields; } - private TableField getTableField(String sortFieldName, T tableType) { - TableField sortField; + /** Retrieves the table field dynamically based on the sort field name. */ + private TableField getTableField(String sortFieldName, T tableType) { try { - Field tableField = - tableType.getClass().getField(sortFieldName.toUpperCase(Locale.ROOT)); - sortField = (TableField) tableField.get(tableType); + Field field = tableType.getClass().getField(sortFieldName.toUpperCase(Locale.ROOT)); + return (TableField) field.get(tableType); } catch (NoSuchFieldException | IllegalAccessException ex) { - String errorMessage = "Could not find table field: %s".formatted(sortFieldName); - throw new InvalidDataAccessApiUsageException(errorMessage, ex); + throw new InvalidDataAccessApiUsageException( + "Could not find table field '%s' in table type '%s'" + .formatted(sortFieldName, tableType.getClass().getSimpleName()), + ex); } - return sortField; } + /** Converts a TableField to a SortField based on the sorting direction. */ private SortField convertTableFieldToSortField( - TableField tableField, Sort.Direction sortDirection) { - if (sortDirection == Sort.Direction.ASC) { - return tableField.asc(); - } else { - return tableField.desc(); - } + TableField tableField, Sort.Direction sortDirection) { + return sortDirection == Sort.Direction.ASC ? tableField.asc() : tableField.desc(); } } diff --git a/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/service/PostService.java b/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/service/PostService.java index 814f0f97a..d85c5c854 100644 --- a/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/service/PostService.java +++ b/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/service/PostService.java @@ -18,25 +18,31 @@ import com.example.jooq.r2dbc.testcontainersflyway.db.tables.records.PostsTagsRecord; import java.util.List; import java.util.UUID; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; import org.jooq.DSLContext; import org.jooq.Record1; import org.jooq.impl.DSL; import org.jooq.impl.SQLDataType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @Service -@RequiredArgsConstructor -@Slf4j public class PostService { + private static final Logger log = LoggerFactory.getLogger(PostService.class); + private final DSLContext dslContext; private final PostRepository postRepository; + public PostService(DSLContext dslContext, PostRepository postRepository) { + this.dslContext = dslContext; + this.postRepository = postRepository; + } + public Flux findAll() { var sql = dslContext @@ -120,9 +126,11 @@ private Mono fetchOrInsertTag(String tagName) { } public Mono> findByKeyword(String keyword, Pageable pageable) { + String sanitizedKeyword = + StringUtils.hasText(keyword) ? keyword.replaceAll("[\n\r\t]", "_") : ""; log.debug( - "findByKeyword with keyword :{} with offset :{} and limit :{}", - keyword, + "findByKeyword with sanitizedKeyword :{} with offset :{} and limit :{}", + sanitizedKeyword, pageable.getOffset(), pageable.getPageSize()); diff --git a/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/service/TagService.java b/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/service/TagService.java index 29b8c6e84..54410fd5f 100644 --- a/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/service/TagService.java +++ b/r2dbc/boot-jooq-r2dbc-sample/src/main/java/com/example/jooq/r2dbc/service/TagService.java @@ -5,17 +5,19 @@ import com.example.jooq.r2dbc.model.response.PaginatedResult; import com.example.jooq.r2dbc.repository.TagRepository; import java.util.UUID; -import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import reactor.core.publisher.Mono; @Service -@RequiredArgsConstructor public class TagService { private final TagRepository tagRepository; + public TagService(TagRepository tagRepository) { + this.tagRepository = tagRepository; + } + public Mono> findAll(Pageable pageable) { return this.tagRepository.findAll(pageable).map(PaginatedResult::new); } @@ -25,6 +27,6 @@ public Mono findById(String id) { } public Mono create(TagDto tagDto) { - return this.tagRepository.save(new Tags(tagDto.name())); + return this.tagRepository.save(new Tags().setName(tagDto.name())); } } diff --git a/r2dbc/boot-jooq-r2dbc-sample/src/main/resources/application-local.properties b/r2dbc/boot-jooq-r2dbc-sample/src/main/resources/application-local.properties index cd50ea92a..f55245ca9 100644 --- a/r2dbc/boot-jooq-r2dbc-sample/src/main/resources/application-local.properties +++ b/r2dbc/boot-jooq-r2dbc-sample/src/main/resources/application-local.properties @@ -3,5 +3,3 @@ spring.r2dbc.username=appuser spring.r2dbc.password=secret spring.flyway.url=jdbc:postgresql://localhost:5432/appdb?maxIdleTime=PT60S -spring.flyway.username=${spring.datasource.username} -spring.flyway.password=${spring.datasource.password} diff --git a/r2dbc/boot-jooq-r2dbc-sample/src/main/resources/application.properties b/r2dbc/boot-jooq-r2dbc-sample/src/main/resources/application.properties index b5a606d5d..91aef3aa1 100644 --- a/r2dbc/boot-jooq-r2dbc-sample/src/main/resources/application.properties +++ b/r2dbc/boot-jooq-r2dbc-sample/src/main/resources/application.properties @@ -4,24 +4,21 @@ server.shutdown=graceful spring.main.allow-bean-definition-overriding=true spring.jmx.enabled=false -################ Logging ##################### -logging.file.name=logs/spring-boot-jooq-r2dbc-sample.log -logging.level.web=INFO -logging.level.sql=INFO -## To enable transaction details logging -#logging.level.org.springframework.transaction=DEBUG -#logging.level.org.springframework.data.r2dbc.connectionfactory=DEBUG - ################ Actuator ##################### management.endpoints.web.exposure.include=configprops,env,health,info,logfile,loggers,metrics management.endpoint.health.show-details=always -################ Database ##################### +################ Database for schema management ##################### spring.datasource.hikari.auto-commit=false spring.flyway.locations=classpath:/db/migration/{vendor} spring.flyway.user=${spring.r2dbc.username} spring.flyway.password=${spring.r2dbc.password} +################ Database properties ##################### +spring.r2dbc.properties.lock_timeout=45000 +spring.r2dbc.properties.statement_timeout=45000 +spring.r2dbc.properties.idle_in_transaction_session_timeout=45000 +spring.r2dbc.properties.connectTimeout=PT59S spring.webflux.problemdetails.enabled=true diff --git a/r2dbc/boot-jooq-r2dbc-sample/src/main/resources/logback-spring.xml b/r2dbc/boot-jooq-r2dbc-sample/src/main/resources/logback-spring.xml index e5c6005ae..7f5d97dcb 100644 --- a/r2dbc/boot-jooq-r2dbc-sample/src/main/resources/logback-spring.xml +++ b/r2dbc/boot-jooq-r2dbc-sample/src/main/resources/logback-spring.xml @@ -4,6 +4,7 @@ + @@ -11,6 +12,7 @@ + @@ -19,5 +21,8 @@ + + + diff --git a/r2dbc/boot-jooq-r2dbc-sample/src/test/java/com/example/jooq/r2dbc/common/ContainerConfig.java b/r2dbc/boot-jooq-r2dbc-sample/src/test/java/com/example/jooq/r2dbc/common/ContainerConfig.java index 73e047cab..0b5983928 100644 --- a/r2dbc/boot-jooq-r2dbc-sample/src/test/java/com/example/jooq/r2dbc/common/ContainerConfig.java +++ b/r2dbc/boot-jooq-r2dbc-sample/src/test/java/com/example/jooq/r2dbc/common/ContainerConfig.java @@ -13,7 +13,7 @@ public class ContainerConfig { @Bean @ServiceConnection PostgreSQLContainer postgreSQLContainer() { - return new PostgreSQLContainer<>(DockerImageName.parse("postgres:17.2-alpine")) + return new PostgreSQLContainer<>(DockerImageName.parse("postgres").withTag("17.2-alpine")) .withCopyFileToContainer( MountableFile.forClasspathResource("init.sql"), "/docker-entrypoint-initdb.d/init.sql"); diff --git a/r2dbc/boot-jooq-r2dbc-sample/src/test/resources/application-test.properties b/r2dbc/boot-jooq-r2dbc-sample/src/test/resources/application-test.properties deleted file mode 100644 index e69de29bb..000000000