Skip to content

Instantly share code, notes, and snippets.

@qbosen
Last active September 27, 2020 12:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save qbosen/86e1e3ff9687db0ccef31b8992130743 to your computer and use it in GitHub Desktop.
Save qbosen/86e1e3ff9687db0ccef31b8992130743 to your computer and use it in GitHub Desktop.
DDD & JPA
/*Domain*/
interface SimpleUser : Validatable {
val id: Long
val name: String
@JvmDefault
fun desc(): String = "$id:$name"
}
interface User : SimpleUser {
val phone: String
fun update(other: User)
}
interface MutableUser : User {
override var id: Long
override var name: String
override var phone: String
}
/*Domain support*/
abstract class UserSupport : AggregateRoot<Long>(), MutableUser {
override fun update(other: User) = run { check(id == other.id); phone = other.phone; name = other.name }
}
interface UserRepository {
fun findById(id: Long): User?
fun findByName(name: String): SimpleUser?
fun save(user: User): User
}
/*Domain service*/
interface UserDomainService {
fun findByName(name: String): SimpleUser?
fun updateUser(other: User): User
}
@Service
class UserDomainServiceImpl(private val userRepository: UserRepository) : UserDomainService {
override fun findByName(name: String): SimpleUser? = userRepository.findByName(name)
override fun updateUser(other: User): User {
val user = userRepository.findById(other.id) ?: throw NotificationException(GlobalError.DataNotFound)
return user.apply { update(other); validate(UpdateGroup::class) }.run(userRepository::save)
}
}
/*Infrastructure*/
@Repository
class UserRepositoryImpl(private val jpaUserRepository: JpaUserRepository) : UserRepository {
override fun findById(id: Long): User? = jpaUserRepository.findByIdOrNull(id)
override fun findByName(name: String): SimpleUser? = jpaUserRepository.findByName(name).orElse(null)
override fun save(user: User): User = jpaUserRepository.save(JpaUser.of(user))
}
/*JPA*/
@Entity
class JpaUser(@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@field:Positive(groups = [UpdateGroup::class])
override var id: Long = 0) : UserSupport() {
@field:NotEmpty
override var name: String = ""
@field:NotEmpty
override var phone: String = ""
companion object {
fun of(user: User): JpaUser = (user as? JpaUser) ?: JpaUser(user.id).also { BeanUtils.copyProperties(user, it) }
}
}
interface JpaUserRepository : JpaRepository<JpaUser, Long> {
fun findByName(name: String): Optional<SimpleUser>
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment