Giter Club home page Giter Club logo

spring-jdbc-plus's Introduction

GitHub release GitHub license

Spring JDBC Plus build Gitter chat Project Diagrams

⚠️ Please do not use 3.3.3
Spring JDBC Plus provides Spring Data JDBC based extension. It provides necessary features when writing more complex SQL than the functions supported by CrudRepository. If you need to use Spring Data JDBC's Persistence features and SQL execution function in combination, Spring JDBC Plus may be an appropriate choice.

Features

  • Support for executing custom SQL SELECT statements

  • Provide BeanParameterSource, MapParameterSource, EntityParameterSource

  • Provide parameter source converters such as Java8Time,Enum, etc.

  • Entity mapping support for complex table join SELECT results

  • AggregateResultSet supports mapping of 1: N result data to Aggregate object graph by LEFT OUTER JOIN lookup

  • JdbcRepository provides insert / update syntax

  • Support for setting Reactive (Flux / Mono) type as the return type of CustomRepository method

  • User Guide

Getting Started (Spring Boot Starter Data JDBC Plus SQL)

  • Gradle

    buildscript {
        repositories {
            mavenCentral()
            mavenLocal()
            maven {
                url "https://repo.spring.io/milestone/"
            }
        }
        dependencies {
            classpath("org.springframework.boot:spring-boot-gradle-plugin:3.3.3")
        }
    }
    
    dependencies {
        implementation("org.springframework.boot:spring-boot-starter-data-jdbc")
        implementation("com.navercorp.spring:spring-boot-starter-data-jdbc-plus-sql:3.3.3.1")
    }
  • Maven

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.3</version>
        <relativePath/>
    </parent>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jdbc</artifactId>
    </dependency>
    
    <dependency>
        <groupId>com.navercorp.spring</groupId>
        <artifactId>spring-boot-starter-data-jdbc-plus-sql</artifactId>
        <version>3.3.3.1</version>
    </dependency>
  • Java Codes

    @Table("n_order")
    @Data
    public class Order {
        @Id
        @Column("order_no")
        private Long orderNo;
    
        @Column("price")
        private long price;
    
        @Column("purchaser_no")
        private String purchaserNo;
    }
    
    public interface OrderRepository extends CrudRepository<Order, Long>, OrderRepositoryCustom {
    }
    
    public interface OrderRepositoryCustom {
        List<Order> findByPurchaserNo(String purchaserNo);
    }
    
    public class OrderRepositoryImpl extends JdbcRepositorySupport<Order> implements OrderRepositoryCustom {
        private final OrderSql sqls;
    
        public OrderRepositoryImpl(EntityJdbcProvider entityJdbcProvider) {
            super(Order.class, entityJdbcProvider);
            this.sql = sqls(OrderSql::new);
        }
    
        @Override
        public List<Order> findByPurchaserNo(String purchaserNo) {
            String sql = this.sql.selectByPurchaserNo();
            return find(sql, mapParameterSource()
                .addValue("purchaserNo", purchaserNo));
        }
    }
  • Groovy codes for SQL

    class OrderSql extends SqlGeneratorSupport {
    
        String selectByPurchaserNo() {
            """
            SELECT ${sql.columns(Order)}
            FROM n_order
            WHERE purchaser_no = :purchaserNo
            """
        }
    }

Cautions when writing SQL

  • Must use named parameters to pass parameters to SQL.
  • If parameter values are concatenated directly to String, it produces bad effects.
    • May cause SQL injection vulnerability.
    • Reduce efficiency of caches in PreparedStatement and NamedParameterJdbcTemplate

Be careful when use string interpolation in Groovy and Kotlin.

  • Bad πŸ‘Ž

    class OrderSql extends SqlGeneratorSupport {
    
        String selectByPurchaserNo(String purchaserNo) {
        """
        SELECT ${sql.columns(Order)}
        FROM n_order
        WHERE purchaser_no = '${purchaserNo}'
        """
        }
    }
  • Good πŸ‘

    class OrderSql extends SqlGeneratorSupport {
    
        String selectByPurchaserNo() {
        """
        SELECT ${sql.columns(Order)}
        FROM n_order
        WHERE purchaser_no = :purchaserNo
        """
        }
    }

Annotation Guide

@SqlTableAlias

@Value
@Builder
@Table("post")
public class PostDto {
    @Id
    Long id;

    @Column
    Post post;

    @SqlTableAlias("p_labels")
    @MappedCollection(idColumn = "board_id")
    Set<Label> labels;
}

@SqlTableAlias is used to attach a separate identifier to the table. @SqlTableAlias can be applied to class, field and method.

@SqlTableAlias is used in the form of @SqlTableAlias("value") .

@SqlFunction

@SqlTableAlias("ts")
static class TestEntityWithNonNullValue {
	@Column
	private Long testerId;

	@Column("tester_nm")
	private String testerName;

	@SqlFunction(expressions = {SqlFunction.COLUMN_NAME, "0"})
	@Column
	private int age;
}

@SqlFunction is typically used to map fields or methods of entity classes to SQL functions.

For example, it can be utilized to define default values for certain fields, or to transform values based on specific conditions.

@SoftDeleteColumn

@Value
@Builder
@Table("article")
static class SoftDeleteArticle {
	@Id
	Long id;

	String contents;

	@SoftDeleteColumn.Boolean(valueAsDeleted = "true")
	boolean deleted;
}

@SoftDeleteColumn supports the soft delete, which is considered as deleted but does not delete actually. This replaces the default 'DELETE' operations to 'UPDATE' operations, by updating specific columns.

You can use value types Boolean or String by Declaring @SoftDeleteColumn.Boolean or @SoftDeleteColumn.String.

Examples

Getting Help

Coding Convention

Building from Source

$  ./gradlew clean build

License

   Copyright 2020-2021 NAVER Corp.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

spring-jdbc-plus's People

Contributors

acktsap avatar alexkarezin avatar apisapple avatar benelog avatar chanhyeong avatar daemin-hwang avatar iam20 avatar jongwooo avatar junoyoon avatar naveross avatar sjh836 avatar wicksome avatar wool0826 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

spring-jdbc-plus's Issues

Support for selectMono

/**
* Select flux flux.
*
* @param <R> the type parameter
* @param sql the sql
* @param params the params
* @param returnType the return type
* @return the flux
*/
protected <R> Flux<R> selectFlux(
String sql,
SqlParameterSource params,
Class<R> returnType) {
RowMapper<R> rowMapper = this.getRowMapper(returnType);
return this.jdbcReactiveTemplate.queryFlux(
sql, this.getEntityJdbcProvider().getJdbcOperations(), params, rowMapper);
}

λΉ„μŠ·ν•˜κ²Œ selectMono도 있으면 쒋을거 κ°™μŠ΅λ‹ˆλ‹€.

401 spring-boot-autoconfigure-data-jdbc-plus:publishMavenJavaPublicationToMavenRepository

Execution failed for task ':spring-boot-autoconfigure-data-jdbc-plus:publishMavenJavaPublicationToMavenRepository'.
> Failed to publish publication 'mavenJava' to repository 'maven'
   > Could not PUT 'https://oss.sonatype.org/service/local/staging/deploy/maven2/com/navercorp/spring/spring-boot-autoconfigure-data-jdbc-plus/3.3.0/spring-boot-autoconfigure-data-jdbc-plus-3.3.0.jar'. Received status code 401 from server: Content access is protected by token

κ·Έλƒ₯ 듀어와 λ΄€λ„€μš”. μ›Ήν”„λ‘œκ·Έλž˜λ° 재미있죠~. κ³΅λΆ€ν•΄λ³΄μ„Έμš”.

Let's safely use smartphones, etc. 😁😊; 슀마트기기. μ•ˆμ „ν•˜κ²Œ μ‚¬μš©ν•©μ‹œλ‹€.😁😊

Long sentences. ; κΈ΄ κΈ€μ΄κ΅°μš”.

...

μ›Ήν”„λ‘œκ·Έλž˜λ°, μžλ™ν™” μ½”λ“œ. 이것도 μ‚¬μš©ν•΄λ³΄μ„Έμš”.
https://github.com/infott2t/SpringAutoCodeJPAEntity3

SpringBoot JPA + QueryDSL.

그런데, μˆ˜μ •μΌμžλ‘œ 검색이 λ˜λŠ” 버그가 μžˆμŠ΅λ‹ˆλ‹€. λ°”κΏ”μ•Όν•˜λŠ”λ°, μ‹œκ°„μ΄ μ—†μ–΄μ„œ... κ·Έ html을 μˆ˜μ •μΌμžλ‘œ λ°”κΏ”μ„œ 써도 되겠죠~.

또, ꡐ회. λ‹€λ…€λ³΄μ„Έμš”. 기독ꡐ. 전화도 ν•΄λ³΄μ„Έμš”. μ‚¬νšŒμ—μ„œ 쉴 κ³³. ν•˜κ³  싢은 말 μ μ–΄λ³΄λ„€μš”.

쒋은 ν•˜λ£¨λ˜μ„Έμš”.

μ €μ˜ κΈ€, 봐 μ£Όμ…”μ„œ κ°μ‚¬ν•©λ‹ˆλ‹€.

Replace AggregateResultSetExtractor with RowDocumentResultSetExtractor

After upgrading to Spring Data JDBC 3.2.2, adopting RowDocumentResultSetExtractor for extracting ResultSets has become standard practice.

In line with these developments, we are evaluating the feasibility of switching from AggregateResultSetExtractor to RowDocumentResultSetExtractor.

If we find it's feasible, we plan to remove these classes:

  • AggregateResultSetExtractor
  • AggregateResultJdbcConverter

Spring Boot Autoconfiguration @ConditionalOnMissingBean μ„€μ • 지원

@IAM20 λ‹˜ Spring Boot AutoConfigure 에 각 Bean 을 ꡐ체할 수 μžˆλ„λ‘ @ConditionalOnMissingBean 이 λΆ™μ—ˆλŠ”λ° μ—¬κΈ° λŒ€μ‘μ΄ μ•ˆλœκ±° κ°™μ•„μš” (3.0.0 λΆ€ν„° μΆ”κ°€)

https://github.com/spring-projects/spring-boot/blob/main/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jdbc/JdbcRepositoriesAutoConfiguration.java#L103

λŒ€μ‘ λΆ€νƒλ“œλ¦½λ‹ˆλ‹€

raw literal string을 μ‚¬μš©ν•˜λŠ” 경우 동적 쿼리 적용 방법 문의

μ΄λ²ˆμ— Spring Data JDBCλ₯Ό μ„ νƒν•˜λ©΄μ„œ https://github.com/benelog/entity-dev/blob/master/src/index.adoc λ₯Ό λ³΄λ©΄μ„œ SQLκ΄€λ¦¬λ°©μ•ˆμ„ κ·ΈλŒ€λ‘œ μ μš©ν•΄λ³΄κ³  μžˆμŠ΅λ‹ˆλ‹€.

μ‚¬μš© 쀑인 μ–Έμ–΄λŠ” 코틀린이고 github예제 처럼 raw literal string을 μ‚¬μš©ν•˜κ³  μžˆμ–΄μ„œ μ•„λž˜μ™€ 같은 ν˜•νƒœλ‘œ μ μš©ν•˜λ©΄ λ¬Έμ œκ°€ μ—†μ§€λ§Œ

object ContentSqls {

    const val selectById =
        """
        SELECT *
        FROM contents
        WHERE c.id = :id
        AND deleted_at IS NOT NULL
        """
}

interface ContentRepository : CrudRepository<Content, Long> {

    @Query(ContentSqls.selectById)
    fun selectById(id: Long): Content?
}

μ•„λž˜μ™€ 같이 동적 쿼리λ₯Ό μ μš©μ„ ν•˜κ³  싢은데

object ContentSqls {

    fun selectById(id:Long) = 
         """
        SELECT *
        FROM contents
        ${
            if (id != null) {
                """
                WHERE id = :id
                AND deleted_at IS NOT NULL    
                """.trimIndent()
            } else {
                """
                    
                """.trimIndent()
            }
        }
        """
}

interface ContentRepository : CrudRepository<Content, Long> {

    @Query(ContentSqls.selectById)
    fun selectById(id: Long): Content?
}

@Query μ• λ…Έν…Œμ΄μ…˜ 내뢀에선 λ©”μ„œλ“œκ°€ μƒμˆ˜νƒ€μž„μ— μƒμ„±λ˜λŠ”κ²ƒμ΄ μ•„λ‹ˆλΌ μ—λŸ¬κ°€ λ°œμƒν•©λ‹ˆλ‹€.
이런 경우 μ–΄λ–€μ‹μœΌλ‘œ 쿼리 λ©”μ„œλ“œλ₯Ό μ μš©ν•  수 μžˆλŠ”μ§€ κΆκΈˆν•©λ‹ˆλ‹€.

μ½”ν‹€λ¦° 지원 문의

syntactic sugarλ₯Ό μœ„ν•œ (예λ₯Ό λ“€μ–΄ μ•„λž˜μ™€ 같은) μ½”ν‹€λ¦° ν™•μž₯ 지원 κ³„νšμ΄ μžˆμ„κΉŒμš”?
(SqlProvider, JdbcRepositorySupport, ...)

class MerchantSql : SqlGeneratorSupport() {
	  fun selectByIdAndSecret() = """
		    SELECT ${sql.columns<MerchantEntity>()}
		    FROM ${sql.tables<MerchantEntity>()}
		    WHERE id = :id
		      AND secret= :secret
	  """
}

inline fun <reified T> SqlProvider.columns(): String = this.columns(T::class.java)

inline fun <reified T> SqlProvider.tables(): String = this.tables(T::class.java)

Add spring-data-jdbc-plus-support module

Objective

Some classes in spring-data-jdbc-plus-sql like SqlGenerator are also needed in spring-data-jdbc-plus-repository for #123

Since there is an spring-jdbc-plus-support module about spring-jdbc,
create spring-data-jdbc-plus-support module about spring-data-jdbc similarly

Add array padding option

byte[] int[] 와 같이 primitive type array μ—μ„œλŠ” νŒ¨λ”©λ˜μ§€ μ•ŠλŠ” 것이 μ’€ 더 μ˜λ„λœ λ™μž‘μΌ κ°€λŠ₯성이 λ†’μŠ΅λ‹ˆλ‹€.
이에 array 의 경우 padding λ˜μ§€ μ•Šλ„λ‘ ν•˜λŠ” option 을 μΆ”κ°€ν•©λ‹ˆλ‹€.


In the case of the primary type arrays like byte[] int[] ... etc.. it may be a more intended operation not to be padded.

Support array padding option will be better for using primitive type usage.

ConvertibleBeanPropertySqlParameterSource μ—μ„œ parameterName 에 prefix μ„€μ • 지원

  • ConvertibleBeanPropertySqlParameterSource μ—μ„œ parameterName 에 prefix λ₯Ό 지정할 수 μžˆλŠ” κΈ°λŠ₯을 μΆ”κ°€ν•œλ‹€.
  • "test." μ΄λΌλŠ” prefix λ₯Ό 담은 ConvertibleBeanPropertySqlParameterSource 객체에 λ‹€μŒμ˜ 클래슀 객체λ₯Ό λ„£μ—ˆμ„ λ•Œ, ":test.value1", ":test.value2" 둜 각 λ³€μˆ˜μ˜ 값을 얻을 수 μžˆλ‹€.
public class Test {
    private String value1;
    private int value2;

   public String getValue1() {
       return this.value1;
   }

   public int getValue2() {
        return this.value2;
    }
}

[κΈ°λŠ₯μ œμ•ˆ1] soft delete 지원

μ•ˆλ…•ν•˜μ„Έμš”? spring data jdbc, naver jdbc plus λ₯Ό μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.
κΈ°λŠ₯을 κ΅¬ν˜„ν•˜λ‹€λ³΄λ‹ˆ, λ°˜λ³΅λ˜λŠ” νŒ¨ν„΄λ“€μ΄ μžˆμ–΄μ„œ, λͺ‡κ°€μ§€ μ μ–΄λ³΄λ €ν•©λ‹ˆλ‹€.

  • soft delete : row λ₯Ό μ‹€μ œλ‘œ μ‚­μ œν•˜λŠ” 것 λŒ€μ‹ , flag 둜 on/off μ œμ–΄
  • WithSoftDelete μΈν„°νŽ˜μ΄μŠ€μ—μ„œ delete* λ©”μ†Œλ“œλ“€μ„ μž¬μ •μ˜
  • κ°€μΉ­ @SoftDeleteFlag μ–΄λ…Έν…Œμ΄μ…˜μœΌλ‘œ flag μ‹λ³„ν•˜μ—¬ sql 을 μƒμ„±ν•˜κ³  Simple*Impl μ—μ„œ μž¬μ •μ˜
    • UPDATE ${table} SET ${softDeleteFlagVar} = false WHERE ${id} = :id
  • (find* μͺ½μ—μ„œλŠ” ByIdAndActive 와 κ°™μ€μ‹μœΌλ‘œ κ°œλ°œμžκ°€ μ•Œμ•„μ„œ..)

κ°μ‚¬ν•©λ‹ˆλ‹€.

JdbcReactiveDaoSupport 와 JdbcDaoSupport 의 μ‚¬μš©μ΄ λΉ„μŠ·ν•΄μ‘ŒμœΌλ©΄ μ’‹κ² μŠ΅λ‹ˆλ‹€.

JdbcDaoSupport λŠ” ν˜„μž¬ μ•„λž˜μ²˜λŸΌ μ‚¬μš©ν•˜λŠ”λ°μš”

public List<Entity> findAll(Criteria criteria) {
    return select(
        sql,
        beanParameterSource(criteria),
        Entitiy.class
    );
}

JdbcReactiveDaoSupport λŠ” μ•„λž˜μ²˜λŸΌ μ‚¬μš©ν•©λ‹ˆλ‹€.

public Flux<Entity> findFlux(Criteria criteria) {
    return selectFlux(
       sql,
       getJdbcOperations(),
       beanParameterSource(criteria),
       getRowMapper(Entitiy.class)
    );
}

μ €λŠ” JdbcReactiveDaoSupport 도 μ‚¬μš©μ‹œμ—

public Flux<Entity> findFlux(Criteria criteria) {
    return selectFlux(
        sql,
        beanParameterSource(criteria),
        Entitiy.class
    );
}

μœ„μ²˜λŸΌλ„ μ‚¬μš© ν•  수 있으면 μ’‹κ² λŠ”λ°μš”.

JdbcReactiveDaoSupport κ°€ JdbcDaoSupport λ₯Ό 상속받고 μžˆμ–΄μ„œ λ‘˜μ΄ λ˜‘κ°™μ΄ μ‚¬μš©ν•  수 μžˆλ„λ‘ λ§Œλ“€ 수 μžˆμ„ 것 κ°™μ•„ μ˜¬λ¦½λ‹ˆλ‹€.

Entity Meta Model Generation

  • 쿼리 μž‘μ„±μ‹œ 컬럼λͺ… λ“± Type Safe ν•œ 쿼리 μž‘μ„±μ„ μ§€μ›ν•˜λŠ” Meta Model Generation

DefaultJdbcParameterSourceConverter 에 νŒŒλΌλ―Έν„° λ°°μ—΄ νƒ€μž…μ€ converting 후에도 λ°°μ—΄λ‘œ λ³€ν™˜ν•©λ‹ˆλ‹€.

ν˜„μž¬λŠ” λ°°μ—΄ νƒ€μž…μ„ List 둜 λ³€ν™˜ν•˜κ³ μžˆλŠ”λ° , NamedParameterJdbcTemplate μ—μ„œ Iterable κ³Ό Array νŒŒλΌλ―Έν„°λ₯Ό λ‹€λ₯΄κ²Œ μ²˜λ¦¬ν•©λ‹ˆλ‹€.

λ”°λΌμ„œ λ°°μ—΄ νŒŒλΌλ―Έν„°λŠ” μ»¨λ²„νŒ… 후에도 λ°°μ—΄λ‘œ μ „λ‹¬ν•©λ‹ˆλ‹€.

@TableAlias causes exception in DML query

@TableAlias causes exception when DML using WHERE clause

For example

@TableAlias("n_bd")
public class Board { 
...
}

This class cannot be updated because of the TableAlias
The Update SQL made by SqlGenerator will be

UPDATE SET `n_board`
...
WHERE `n_bd`.`id` = :id;

This SQL makes the table not found exception.

Move flux producer gen time.

ν˜„μž¬ queryFlux 의 producer gen time 은 μ•„λž˜μ™€ κ°™μŠ΅λ‹ˆλ‹€.

image

μ΄λŠ” ν•œ μš”μ²­μ— ν•œ 개의 Flux 만 μ‚¬μš©ν•˜λŠ” κ²½μš°μ—” λ¬Έμ œκ°€ λ˜μ§€ μ•ŠλŠ”λ°μš”.
μ—¬λŸ¬ 개의 Flux λ₯Ό μ‘°ν•©ν•  λ•ŒλŠ” λ¬Έμ œκ°€ λ©λ‹ˆλ‹€.

ex. ) Flux.concat, Flux.flatMapSequential

이런 경우 subscribe κ°€ λ˜κΈ°λ„ 전에 Producer κ°€ μƒμ„±λ˜μ–΄ 데이터λ₯Ό λ°›μ•„μ˜€λ‹€κ°€ Backpressure 둜 producer κ°€ μ£½λŠ”λ°μš”
이λ₯Ό λ°©μ§€ν•˜κΈ°μœ„ν•΄ queryFlux 의 producer gen time 을 μ•„λž˜μ™€ 같이 λ³€κ²½ν•˜λ €κ³  ν•©λ‹ˆλ‹€.

image

RelationalEvent λ°œν–‰μ€‘λ‹¨

μ•ˆλ…•ν•˜μ„Έμš”? 정말 잘 μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

spring-data-jdbc λŠ” 기본적으둜 RelationalEvent λ₯Ό λͺ¨λ“  life cycle μ—μ„œ λ°œν–‰ν•©λ‹ˆλ‹€.
https://docs.spring.io/spring-data/relational/reference/jdbc/events.html

이것을 λΉ„ν™œμ„±ν™”ν•˜κΈ° μœ„ν•΄μ„œλŠ” JdbcAggregateTemplate.setEntityLifecycleEventsEnabled(false) λ₯Ό ν•΄μ•Όν•˜λŠ”λ°μš”,
https://docs.spring.io/spring-data/jdbc/docs/3.2.2/api/org/springframework/data/jdbc/core/JdbcAggregateTemplate.html#setEntityLifecycleEventsEnabled(boolean)

bean 을 μž¬μ •μ˜ν•˜λ”λΌλ„, λ³Έ ν”„λ‘œμ νŠΈμ—μ„œλŠ” μ•„λž˜μ™€ 같이 μ‚¬μš©?ν•˜κ³ μžˆμ–΄μ„œ 먹지λ₯Ό μ•ŠλŠ” 것 κ°™μŠ΅λ‹ˆλ‹€.
https://github.com/naver/spring-jdbc-plus/blob/main/spring-data-jdbc-plus-repository/src/main/java/com/navercorp/spring/data/jdbc/plus/repository/support/JdbcPlusRepositoryFactory.java#L76

[λ‹¨μˆœμ§ˆλ¬Έ] JdbcRepository μΈν„°νŽ˜μ΄μŠ€ @NoRepositoryBean

μ•ˆλ…•ν•˜μ„Έμš”?

μ•„λž˜ λ¬Έμ„œλ₯Ό λ³΄λ‹ˆ, JdbcRepository μΈν„°νŽ˜μ΄μŠ€μ— @NoRepositoryBean λ₯Ό λΆ™μ—¬μ•Όν•˜λŠ”κ²Œ μ•„λ‹Œκ°€ ν˜Όλ™μ΄λ˜λ„€μš”..

잘λͺ»μ΄ν•΄ν•œ 뢀뢄이 μžˆμ„κΉŒμš”?

Failed to expand primitive type array

primitive array cannot be cast to Object array

Caused by: java.lang.ClassCastException: class [B cannot be cast to class [Ljava.lang.Object; ([B and [Ljava.lang.Object; are in module java.base of loader 'bootstrap')
	at com.navercorp.spring.jdbc.plus.support.parametersource.converter.IterableExpandPadding.expandIfIterable(IterableExpandPadding.java:94)
	at com.navercorp.nbaset.spring.data.jdbc.namedparam.NbaseSqlIdentifierParameterSource.getValue(NbaseSqlIdentifierParameterSource.java:110)
	at org.springframework.jdbc.core.namedparam.NamedParameterUtils.substituteNamedParameters(NamedParameterUtils.java:302)
	at com.navercorp.nbaset.spring.jdbc.namedparam.NbaseNamedParameterJdbcTemplate.getPreparedStatementCreatorFactory(NbaseNamedParameterJdbcTemplate.java:86)
	at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.getPreparedStatementCreator(NamedParameterJdbcTemplate.java:424)
	at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.getPreparedStatementCreator(NamedParameterJdbcTemplate.java:402)
	at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.update(NamedParameterJdbcTemplate.java:331)
	at com.navercorp.nbaset.spring.data.jdbc.strategy.NbaseInsertStrategyFactory$DefaultNbaseInsertStrategy.execute(NbaseInsertStrategyFactory.java:71)
	at com.navercorp.nbaset.spring.data.jdbc.strategy.NbaseNodeDataAccessStrategy.insert(NbaseNodeDataAccessStrategy.java:122)
	at org.springframework.data.jdbc.core.JdbcAggregateChangeExecutionContext.executeInsertRoot(JdbcAggregateChangeExecutionContext.java:83)
	at org.springframework.data.jdbc.core.AggregateChangeExecutor.execute(AggregateChangeExecutor.java:85)
	... 122 more

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.