JPA конвертировать из dto в сущность с рекурсией перед сохранением - PullRequest
0 голосов
/ 18 сентября 2018

Я работаю над, казалось бы, простой задачей, но я ищу "правильный" способ сделать это.

DTO

Сначала позвольте мне представить мои классы (если хотите, DTO)

Первый класс - пользователь, чтобы предотвратить рекурсию, и мне не нужна бесконечная глубинаЯ создал класс UserInfo, который содержит все, кроме связей с другими классами.

data class User(
        val id: Long,
        val name: String,
        val follows: List<UserInfo>,
        val followedBy: List<UserInfo>
)

data class UserInfo(
        val id: Long,
        val name: String
)

Entity

Далее класс сущности.Это будет работать, как и ожидалось, создаст таблицу и готов к работе.

@Entity
@Table(name = "user")
data class UserEntity(
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(nullable = false)
        val id: Long,
        val name: String,

        @JoinTable(name = "followers",
                joinColumns = [JoinColumn(name = "follower", referencedColumnName = "id", nullable = false)],
                inverseJoinColumns = [JoinColumn(name = "followed", referencedColumnName = "id", nullable = false)])
        @ManyToMany(fetch = FetchType.LAZY)
        val follows: List<UserEntity>,

        @ManyToMany(mappedBy = "follows", fetch = FetchType.LAZY)
        val followedBy: List<UserEntity>
)

Mappers

Используя функции расширения Kotlin, я создал 2 картографа.Первый маппер немного многословен, но ничего особенного.

fun UserEntity.toUser() = User(
        id = this.id,
        name = this.name,
        follows = this.follows.map { UserInfo(id = it.id, name = it.name) },
        followedBy = this.followedBy.map { UserInfo(id = it.id, name = it.name) }
)

Второй маппер - это то, где задача лежит , поскольку именно здесь сущность ожидает список UserEntity,который не может быть создан из UserInfo, только из User, который в данный момент недоступен.

fun User.toUserEntity() = UserEntity(
        id = this.id,
        name = this.name,
        followedBy = listOf(),  // ????
        follows = listOf() // ????
)

DAO

Теперь в DAO объект User делаетне имеет своих последователей по ссылкам, что делает невозможным сохранение.

class UserDao @Inject constructor(private val em: EntityManager) {

    fun findUserById(id: Long): User = em
            .find(UserEntity::class.java, "id")
            .toUser()

    fun save(user: User) {
        val entity = user.toUserEntity()

        // follows and followedBy lists are empty!
        em.persist(entity)
    }
}

Каков был бы правильный подход для этого?

...