Could not safely identify store assignment for repository candidate interface
๐ซ ์๋ฌ ์ํฉ
Redis ๋ด์ Refresh token ๊ฐ์ ๋ค๋ฃจ๊ธฐ ์ํด CrudRepository ๋ฅผ ์ฌ์ฉํ๊ณ , RDBMS ๋ด์ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃจ๊ธฐ ์ํด JpaRepository ๋ฅผ ์ฌ์ฉํ์ต๋๋ค.
ํ๋ก์ ํธ๋ฅผ ์คํํ๋ฉด ๋จ๋ ์ฌ๋ฌ ๋ก๊ทธ ์ค ์๋ฌ๋ ์๋์ง๋ง, ๋ฐ๊ฐ์ง ์์ INFO ๋ก๊ทธ๊ฐ 2๊ฐ์ ์์ญ์ผ๋ก ๋๋์ด 7๊ฐ ์ ๋ ๋ฐ๋ณต๋๋ ๊ฒ์ ํ์ธํ์ต๋๋ค. ์ํฐํฐ ํด๋์ค ์ ๋งํผ ๋ฐ๋ณต ๋์๊ณ , ์๋์ฒ๋ผ ๋ก๊ทธ๊ฐ ์ถ๋ ฅ๋์ต๋๋ค.
- A ์์ญ: Spring Data JPA
2023-06-18 19:10:30.731 INFO 4986 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
2023-06-18 19:10:30.670 INFO 4986 --- [ main] .RepositoryConfigurationExtensionSupport : Spring Data JPA - Could not safely identify store assignment for repository candidate interface jparest.practice.auth.jwt.RefreshTokenRepository; If you want this repository to be a JPA repository, consider annotating your entities with one of these annotations: javax.persistence.Entity, javax.persistence.MappedSuperclass (preferred), or consider extending one of the following types with your repository: org.springframework.data.jpa.repository.JpaRepository
- B ์์ญ: Spring Data Redis
2023-06-18 19:10:30.741 INFO 4986 --- [ main] .RepositoryConfigurationExtensionSupport : Spring Data Redis - Could not safely identify store assignment for repository candidate interface jparest.practice.group.repository.GroupRepository; If you want this repository to be a Redis repository, consider annotating your entities with one of these annotations: org.springframework.data.redis.core.RedisHash (preferred), or consider extending one of the following types with your repository: org.springframework.data.keyvalue.repository.KeyValueRepository
2023-06-18 19:10:30.741 INFO 4986 --- [ main] .RepositoryConfigurationExtensionSupport : Spring Data Redis - Could not safely identify store assignment for repository candidate interface jparest.practice.group.repository.UserGroupRepository; If you want this repository to be a Redis repository, consider annotating your entities with one of these annotations: org.springframework.data.redis.core.RedisHash (preferred), or consider extending one of the following types with your repository: org.springframework.data.keyvalue.repository.KeyValueRepository
2023-06-18 19:10:30.741 INFO 4986 --- [ main] .RepositoryConfigurationExtensionSupport : Spring Data Redis - Could not safely identify store assignment for repository candidate interface jparest.practice.invite.repository.InviteRepository; If you want this repository to be a Redis repository, consider annotating your entities with one of these annotations: org.springframework.data.redis.core.RedisHash (preferred), or consider extending one of the following types with your repository: org.springframework.data.keyvalue.repository.KeyValueRepository
2023-06-18 19:10:30.741 INFO 4986 --- [ main] .RepositoryConfigurationExtensionSupport : Spring Data Redis - Could not safely identify store assignment for repository candidate interface jparest.practice.rest.repository.GroupRestRepository; If you want this repository to be a Redis repository, consider annotating your entities with one of these annotations: org.springframework.data.redis.core.RedisHash (preferred), or consider extending one of the following types with your repository: org.springframework.data.keyvalue.repository.KeyValueRepository
2023-06-18 19:10:30.742 INFO 4986 --- [ main] .RepositoryConfigurationExtensionSupport : Spring Data Redis - Could not safely identify store assignment for repository candidate interface jparest.practice.rest.repository.RestRepository; If you want this repository to be a Redis repository, consider annotating your entities with one of these annotations: org.springframework.data.redis.core.RedisHash (preferred), or consider extending one of the following types with your repository: org.springframework.data.keyvalue.repository.KeyValueRepository
2023-06-18 19:10:30.742 INFO 4986 --- [ main] .RepositoryConfigurationExtensionSupport : Spring Data Redis - Could not safely identify store assignment for repository candidate interface jparest.practice.user.repository.UserRepository; If you want this repository to be a Redis repository, consider annotating your entities with one of these annotations: org.springframework.data.redis.core.RedisHash (preferred), or consider extending one of the following types with your repository: org.springframework.data.keyvalue.repository.KeyValueRepository
๋ก๊ทธ๋ ๋๊ฐ์ ์์ญ์ผ๋ก ๋๋์๊ณ , ์ฝ์ด๋ณด๋ฉด
โSpring Data JPA: ์ํฐํฐ์ ๋ ํฌ์งํ ๋ฆฌ์ ๋ํด ์๋ณํ ์ ์๋ค. ๋ง์ฝ ์ด ๋ ํฌ์งํ ๋ฆฌ๋ฅผ JPA repository๋ก ๋ง๋ค๋ ค๋ฉด @Entity ์ด๋ ธํ ์ด์ ์ ์ฌ์ฉํด๋ผโ
โSpring Data Redis: ์ํฐํฐ์ ๋ ํฌ์งํ ๋ฆฌ์ ๋ํด ์๋ณํ ์ ์๋ค. ๋ง์ฝ ์ด ๋ ํฌ์งํ ๋ฆฌ๋ฅผ Redis repository๋ก ๋ง๋ค๋ ค๋ฉด @RedisHash ์ด๋ ธํ ์ด์ ์ ์ฌ์ฉํด๋ผโ
์ด๋ฐ ๋ด์ฉ์ธ ๊ฒ ๊ฐ์ต๋๋ค. ์ ๋ ํฌ์งํ ๋ฆฌ๋ฅผ ์๋ณํ ์ ์๋์ง ์๋ฌธ์ด์์ต๋๋ค.
๐ ์๋ฌ ์์ธ
JpaRepository, CrudRepository ๋ ๋ชจ๋ Repository ์ธํฐํ์ด์ค๋ฅผ ํ์ฅํ ๊ฒ์ ๋๋ค.
๋ฌธ์ ๋ @Entity ๋ฅผ ์ฌ์ฉํ์ง ์๊ณ Respository ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉ(Redis ์ ๊ฒฝ์ฐ)ํ์ ๋, Spring ์ด โRepository ๋ก๋ถํฐ ์์ฑ๋ ๋ฉ์๋๋ฅผ ์ด๋ป๊ฒ ์ฌ์ฉํ์ง?โ ํ๊ณ ์๋ฌธ์ ํ๊ณ ์ค์ค๋ก ์ฐพ๋๋ค๊ณ ํฉ๋๋ค.
๋ฐ๋ผ์, ์๋์ฒ๋ผ Redis ์์ CrudRepository ๋ฅผ ์ฌ์ฉํ๊ณ @Entity ๋ฅผ ์ฌ์ฉํ์ง ์์์ผ๋ฏ๋ก Spring์ ๊ฐ Repository ์ ๋ฉ์๋ ๋ค์ ์ด๋ป๊ฒ ๊ตฌํํด์ผํ๋ ์ง ์ฐพ์ต๋๋ค.
package jparest.practice.auth.jwt;
...
@Getter
@RedisHash("refresh")
@NoArgsConstructor
public class RefreshToken {
@Id
private String id;
private String refreshToken;
...
}
public interface RefreshTokenRepository extends CrudRepository<RefreshToken, String> {
}
๊ทธ๋ฌํ ํ์ ๊ณผ์ ์ด (JpaRepository x N) + (CrudRepository x M) ๋งํผ ์ด๋ฃจ์ด์ง๊ฑฐ๋ผ๊ณ ์๊ฐ์ด ๋ญ๋๋ค. (์ถ์ธก์ ๋๋ค.)
๐ ํด๊ฒฐ ๋ฐฉ๋ฒ
1. EnableRedisRepositories ์ถ๊ฐ
package jparest.practice.common.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
@Configuration
@EnableRedisRepositories(basePackages = "jparest.practice.auth.jwt")
public class RedisConfig {
}
EnableRedisRepositories ์ด๋ ธํ ์ด์ ์ ์ด์ฉํ๋ฉด, RedisRepository ๋ฅผ ํ์ฑํ ์ํค๊ณ , ๋น ์ค์บ๋ ๋ฒ์๋ฅผ ์ง์ ํ ์ ์์ต๋๋ค. ์ด๋ ๊ฒ ์ง์ ํด์ฃผ๋ RedisRepository ์ ๋ํ ํ์์ ๋ค๋ฅธ ๊ฒฝ๋กํด์ ํ์ง ์์์ B ์์ญ ๋ก๊ทธ๊ฐ ์ถ๋ ฅ๋์ง ์์์ต๋๋ค.
2. EnableJpaRepositories ์ถ๊ฐ
package jparest.practice.common.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
@Configuration
@EnableJpaRepositories(basePackages = "jparest.practice",
excludeFilters = @ComponentScan.Filter(
type = FilterType.ASPECTJ, pattern = "jparest.practice.auth.jwt.*"
)
)
public class JpaConfig {
}
์ฌ์ ํ A ๋ก๊ทธ๋ ์ถ๋ ฅ๋์ต๋๋ค. ๊ทธ๋์ JpaRepository ๋ฅผ ํ์ฑํ ์ํค๊ณ , ๋น ์ค์บ๋ ๋ฒ์๋ฅผ ์ง์ ํ๊ธฐ ์ํด ์ถ๊ฐ EnableJpaRepositories ์ด๋ ธํ ์ด์ ์ ์ถ๊ฐํ์ต๋๋ค. ์ฃผ์ํ ์ ์ @Entity ๊ฐ ์๋๋ฐ Repository ๋ฅผ ์ฌ์ฉํ๋ฉด Spring ์ด ์ด๋ป๊ฒ ๋ฉ์๋๋ฅผ ๊ตฌํํ ์ง ์ฐพ๋๋ค๊ณ ํ์ต๋๋ค. ๋ฐ๋ผ์ Redis ๋ฅผ ์ฌ์ฉํ๋ ๊ณณ์ ๋น ์ค์บ๋ ๋ฒ์์์ ์ ์ธ์์ผฐ์ต๋๋ค. EnableJpaRepositories ๊น์ง ์ ์ฉํ๋๋ ๋ชจ๋ ๋ก๊ทธ๊ฐ ์ฌ๋ผ์ง ๊ฒ์ ํ์ธํ ์ ์์์ต๋๋ค.
2023-06-18 20:42:02.762 INFO 5431 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 141 ms. Found 6 JPA repository interfaces.
2023-06-18 20:42:02.763 INFO 5431 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
2023-06-18 20:42:02.763 INFO 5431 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
2023-06-18 20:42:02.772 INFO 5431 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 1 Redis repository interfaces.