Skip to content

Commit c6f2d9a

Browse files
committed
Refactor JPA entities to use proper associations.
1 parent 72b464f commit c6f2d9a

File tree

9 files changed

+60
-61
lines changed

9 files changed

+60
-61
lines changed

core-impl/src/main/kotlin/io/github/gunkim/realworld/infrastructure/jpa/article/dao/ArticleDao.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ interface ArticleDao : JpaRepository<ArticleEntity, Int>, JpaSpecificationExecut
4242
"""
4343
SELECT a
4444
FROM users u
45-
INNER JOIN user_follow uf ON uf.followerUserDatabaseId = u.databaseId
46-
INNER JOIN article a ON a.authorEntity.databaseId = uf.followeeUserDatabaseId
45+
INNER JOIN user_follow uf ON uf.followerEntity = u
46+
INNER JOIN article a ON a.authorEntity = uf.followeeEntity
4747
WHERE u.id = :userId
4848
"""
4949
)
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package io.github.gunkim.realworld.infrastructure.jpa.article.dao
22

3+
import io.github.gunkim.realworld.infrastructure.jpa.article.model.ArticleEntity
34
import io.github.gunkim.realworld.infrastructure.jpa.article.model.FavoriteEntity
5+
import io.github.gunkim.realworld.infrastructure.jpa.user.model.UserEntity
46
import org.springframework.data.jpa.repository.JpaRepository
57

68
interface ArticleFavoriteDao : JpaRepository<FavoriteEntity, Int> {
7-
fun deleteByArticleEntityDatabaseIdAndUserEntityDatabaseId(articleDatabaseId: Int, userDatabaseId: Int)
9+
fun deleteByArticleEntityAndUserEntity(articleEntity: ArticleEntity, userEntity: UserEntity)
810
}

core-impl/src/main/kotlin/io/github/gunkim/realworld/infrastructure/jpa/article/model/ArticleEntity.kt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,6 @@ class ArticleEntity(
130130
return result
131131
}
132132

133-
override fun toString(): String {
134-
return "ArticleJpaEntity(databaseId=$databaseId, id=$id, author=$authorEntity, articleTagJpaEntities=$tagEntities, createdAt=$createdAt, updatedAt=$updatedAt, slug=$slug, title='$title', description='$description', body='$body')"
135-
}
136-
137133
companion object {
138134
fun from(article: Article): ArticleEntity = with(article) {
139135
ArticleEntity(

core-impl/src/main/kotlin/io/github/gunkim/realworld/infrastructure/jpa/article/model/ArticleTagEntity.kt

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,6 @@ class ArticleTagEntity(
5353
return result
5454
}
5555

56-
override fun toString(): String {
57-
return "ArticleTagJpaEntity(databaseId=$databaseId, tag=$tagEntity, createdAt=$createdAt, updatedAt=$updatedAt)"
58-
}
59-
60-
6156
companion object {
6257
fun fromTagEntity(tag: TagEntity) = ArticleTagEntity(
6358
tagEntity = tag,

core-impl/src/main/kotlin/io/github/gunkim/realworld/infrastructure/jpa/article/repository/ArticleRepositoryImpl.kt

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,37 +25,37 @@ class ArticleRepositoryImpl(
2525
private val articleFavoriteDao: ArticleFavoriteDao,
2626
) : ArticleRepository, ArticleReadRepository by articleReadRepository {
2727
override fun save(article: Article): Article {
28-
val articleJpaEntity = convertArticleToJpaEntity(article)
29-
return articleDao.save(articleJpaEntity)
28+
val articleEntity = convertArticleToEntity(article)
29+
return articleDao.save(articleEntity)
3030
}
3131

3232
override fun delete(article: Article) {
33-
articleDao.delete(convertArticleToJpaEntity(article))
33+
articleDao.delete(convertArticleToEntity(article))
3434
}
3535

3636
override fun favorite(article: Article, user: User) {
37-
val (articleJpaEntity, userJpaEntity) = mapToJpaEntities(article, user)
37+
val (articleEntity, userEntity) = mapToEntities(article, user)
3838
articleFavoriteDao.save(
3939
FavoriteEntity.of(
40-
articleJpaEntity,
41-
userJpaEntity
40+
articleEntity = articleEntity,
41+
userEntity = userEntity
4242
)
4343
)
4444
}
4545

4646
override fun unFavorite(article: Article, user: User) {
47-
val (articleJpaEntity, userJpaEntity) = mapToJpaEntities(article, user)
48-
articleFavoriteDao.deleteByArticleEntityDatabaseIdAndUserEntityDatabaseId(
49-
articleJpaEntity.databaseId!!,
50-
userJpaEntity.databaseId!!
47+
val (articleEntity, userEntity) = mapToEntities(article, user)
48+
articleFavoriteDao.deleteByArticleEntityAndUserEntity(
49+
articleEntity = articleEntity,
50+
userEntity = userEntity
5151
)
5252
}
5353

54-
private fun mapToJpaEntities(article: Article, user: User) =
55-
convertArticleToJpaEntity(article) to UserEntity.from(user)
54+
private fun mapToEntities(article: Article, user: User) =
55+
convertArticleToEntity(article) to UserEntity.from(user)
5656

57-
private fun convertArticleToJpaEntity(article: Article) =
58-
ArticleEntity.from(article, convertTagsToJpaEntities(article))
57+
private fun convertArticleToEntity(article: Article) =
58+
ArticleEntity.from(article, convertTagsToEntities(article))
5959

6060
/**
6161
* Converts the `tags` associated with the provided `article` into a list of `ArticleTagJpaEntity`.
@@ -66,7 +66,7 @@ class ArticleRepositoryImpl(
6666
* @param article The article whose tags need to be converted to JPA entities.
6767
* @return A list of `ArticleTagJpaEntity` objects corresponding to the tags of the article.
6868
*/
69-
private fun convertTagsToJpaEntities(article: Article): List<ArticleTagEntity> {
69+
private fun convertTagsToEntities(article: Article): List<ArticleTagEntity> {
7070
if (article is ArticleEntity) return article.tagEntities
7171

7272
val tags = article.tags
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package io.github.gunkim.realworld.infrastructure.jpa.user.dao
22

3-
import io.github.gunkim.realworld.infrastructure.jpa.user.model.FollowJpaEntity
3+
import io.github.gunkim.realworld.infrastructure.jpa.user.model.FollowEntity
4+
import io.github.gunkim.realworld.infrastructure.jpa.user.model.UserEntity
45
import org.springframework.data.jpa.repository.JpaRepository
56

6-
interface FollowDao : JpaRepository<FollowJpaEntity, Long> {
7-
fun deleteByFolloweeUserDatabaseIdAndFollowerUserDatabaseId(followingDatabaseId: Int, followerDatabaseId: Int)
7+
interface FollowDao : JpaRepository<FollowEntity, Long> {
8+
fun deleteByFolloweeEntityAndFollowerEntity(followeeUserEntity: UserEntity, followerUserEntity: UserEntity)
89
}

core-impl/src/main/kotlin/io/github/gunkim/realworld/infrastructure/jpa/user/dao/UserDao.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ interface UserDao : JpaRepository<UserEntity, Long> {
1515
SELECT followee.id
1616
FROM users u
1717
INNER JOIN
18-
user_follow f ON f.followerUserDatabaseId = u.databaseId
18+
user_follow f ON f.followerEntity = u
1919
INNER JOIN
20-
users followee ON f.followeeUserDatabaseId = followee.databaseId
20+
users followee ON f.followeeEntity = followee
2121
WHERE u.id = :userId
2222
"""
2323
)

core-impl/src/main/kotlin/io/github/gunkim/realworld/infrastructure/jpa/user/model/FollowJpaEntity.kt renamed to core-impl/src/main/kotlin/io/github/gunkim/realworld/infrastructure/jpa/user/model/FollowEntity.kt

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,38 @@ package io.github.gunkim.realworld.infrastructure.jpa.user.model
22

33
import jakarta.persistence.Column
44
import jakarta.persistence.Entity
5+
import jakarta.persistence.FetchType
56
import jakarta.persistence.GeneratedValue
67
import jakarta.persistence.GenerationType
78
import jakarta.persistence.Id
9+
import jakarta.persistence.JoinColumn
10+
import jakarta.persistence.ManyToOne
811
import java.time.Instant
912

1013
@Entity(name = "user_follow")
11-
class FollowJpaEntity(
14+
class FollowEntity(
1215
@Id
1316
@Column(name = "follow_id")
1417
@GeneratedValue(strategy = GenerationType.IDENTITY)
1518
val databaseId: Int?,
16-
@Column(name = "followee_id")
17-
val followeeUserDatabaseId: Int,
18-
@Column(name = "follower_id")
19-
val followerUserDatabaseId: Int,
19+
@ManyToOne(fetch = FetchType.EAGER)
20+
@JoinColumn(name = "followee_id")
21+
val followeeEntity: UserEntity,
22+
@ManyToOne(fetch = FetchType.EAGER)
23+
@JoinColumn(name = "follower_id")
24+
val followerEntity: UserEntity,
2025
val createdAt: Instant,
2126
val updatedAt: Instant = Instant.now(),
2227
) {
2328
override fun equals(other: Any?): Boolean {
2429
if (this === other) return true
2530
if (javaClass != other?.javaClass) return false
2631

27-
other as FollowJpaEntity
32+
other as FollowEntity
2833

2934
if (databaseId != other.databaseId) return false
30-
if (followeeUserDatabaseId != other.followeeUserDatabaseId) return false
31-
if (followerUserDatabaseId != other.followerUserDatabaseId) return false
35+
if (followeeEntity != other.followeeEntity) return false
36+
if (followerEntity != other.followerEntity) return false
3237
if (createdAt != other.createdAt) return false
3338
if (updatedAt != other.updatedAt) return false
3439

@@ -37,19 +42,19 @@ class FollowJpaEntity(
3742

3843
override fun hashCode(): Int {
3944
var result = databaseId ?: 0
40-
result = 31 * result + followeeUserDatabaseId
41-
result = 31 * result + followerUserDatabaseId
45+
result = 31 * result + followeeEntity.hashCode()
46+
result = 31 * result + followerEntity.hashCode()
4247
result = 31 * result + createdAt.hashCode()
4348
result = 31 * result + updatedAt.hashCode()
4449
return result
4550
}
4651

4752
companion object {
48-
fun of(followeeId: Int, followerId: Int) =
49-
FollowJpaEntity(
53+
fun of(followeeUserEntity: UserEntity, followerUserEntity: UserEntity) =
54+
FollowEntity(
5055
databaseId = null,
51-
followeeUserDatabaseId = followeeId,
52-
followerUserDatabaseId = followerId,
56+
followeeEntity = followeeUserEntity,
57+
followerEntity = followerUserEntity,
5358
createdAt = Instant.now()
5459
)
5560
}

core-impl/src/main/kotlin/io/github/gunkim/realworld/infrastructure/jpa/user/repository/UserRepositoryImpl.kt

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import io.github.gunkim.realworld.domain.user.repository.UserReadRepository
77
import io.github.gunkim.realworld.domain.user.repository.UserRepository
88
import io.github.gunkim.realworld.infrastructure.jpa.user.dao.FollowDao
99
import io.github.gunkim.realworld.infrastructure.jpa.user.dao.UserDao
10-
import io.github.gunkim.realworld.infrastructure.jpa.user.model.FollowJpaEntity
10+
import io.github.gunkim.realworld.infrastructure.jpa.user.model.FollowEntity
1111
import io.github.gunkim.realworld.infrastructure.jpa.user.model.UserEntity
1212
import org.springframework.beans.factory.annotation.Qualifier
1313
import org.springframework.stereotype.Repository
@@ -26,32 +26,32 @@ class UserRepositoryImpl(
2626
}
2727

2828
override fun follow(followerId: UserId, followeeId: UserId) {
29-
val (followerDatabaseId, followeeDatabaseId) = resolveUserDatabaseIds(followerId, followeeId)
29+
val (follower, followee) = resolveUserEntity(followerId, followeeId)
3030
followDao.save(
31-
FollowJpaEntity.of(
32-
followeeId = followeeDatabaseId,
33-
followerId = followerDatabaseId
31+
FollowEntity.of(
32+
followerUserEntity = follower,
33+
followeeUserEntity = followee
3434
)
3535
)
3636
}
3737

3838
override fun unfollow(followerId: UserId, followeeId: UserId) {
39-
val (followerDatabaseId, followeeDatabaseId) = resolveUserDatabaseIds(followerId, followeeId)
40-
followDao.deleteByFolloweeUserDatabaseIdAndFollowerUserDatabaseId(
41-
followingDatabaseId = followeeDatabaseId,
42-
followerDatabaseId = followerDatabaseId
39+
val (follower, followee) = resolveUserEntity(followerId, followeeId)
40+
followDao.deleteByFolloweeEntityAndFollowerEntity(
41+
followeeUserEntity = followee,
42+
followerUserEntity = follower
4343
)
4444
}
4545

46-
private fun resolveUserDatabaseIds(followerId: UserId, followeeId: UserId): Pair<Int, Int> {
47-
val followerDatabaseId = getUserDatabaseIdOrThrow(followerId)
48-
val followeeDatabaseId = getUserDatabaseIdOrThrow(followeeId)
46+
private fun resolveUserEntity(followerId: UserId, followeeId: UserId): Pair<UserEntity, UserEntity> {
47+
val follower = getUserEntityOrThrow(followerId)
48+
val followee = getUserEntityOrThrow(followeeId)
4949

50-
return followerDatabaseId to followeeDatabaseId
50+
return follower to followee
5151
}
5252

53-
private fun getUserDatabaseIdOrThrow(userId: UserId): Int {
54-
return userDao.findById(userId)?.databaseId
53+
private fun getUserEntityOrThrow(userId: UserId): UserEntity {
54+
return userDao.findById(userId)
5555
?: throw UserNotFoundException.fromId(userId)
5656
}
5757
}

0 commit comments

Comments
 (0)