I would strongly advise against that. It does thin...
# spring
j
I would strongly advise against that. It does things in a way that goes against the philosophy of Spring, and DI in general. And it makes the code impossible to test. Say you create a mock repository and inject it into a service that you want to unit-test. The save() method of the user will not use the mocked repository. It will try to access a global USER_REPOSITORY variable, which might or might not be initialized depending on which tests have been run before. DI is your friend. It’s used for good reasons.
🚫 2
👍🏾 1
j
A bit related but I've always wondered how to do "proper" DDD with Spring. By proper I mean not using anemic domain model which is the case in all samples I've found. So the domain would need to access repositories and also handle transactions etc. a bit different way
Also if someone knows proper non-trivial DDD example for Spring let me know 🙂
k
I think the problem is, that you try to use JPA entities as your domain objects. and then entities are managed by PersistenceContext and in DI you use spring context
c
@Jukka Papinkivi Proper DDD in spring == Axon framework 🙂 @jbnizet "Impossible to test" is a bit harsh. In fact this approach is perfectly testable. In unit tests you mock
save()
method, there is no spring to initialize the "static" variable. After encountering this once in the codebase you'll remember to do that. It's only confusing for the first time, which is a shame, but manageable. In integration tests there should be no mocks, or they should be handled on the
@TestConfiguration
level, not injected directly into the services. If you're injecting mocks directly, then this is not an integration test and there should be no Spring context to worry about.
You can also mock the variable
*_REPOSITORY
directly, but then it either can't be private or you'll do reflection magic, which is too dirty to consider doing each time you want it mocked. If you have a generic repository, it could be something like this:
Copy code
StaticRepositoryInitializerConfigKt.STATIC_REPOSITORY = mockk<EntityRepository>() { /*...*/ }
But I would not recommend that, as someone could define different mock and tests could conflict with each other. That's why static/global stuff should always be approached carefully.
I do agree that "it goes against...", but sometimes it's just too nice to avoid just because of philosophy 🙂 I'm definitely not trading
Copy code
class UserService {
  fun createUser() {
    CreateUser(...).execute()
    UserCreated(...).publish()
  }
for
Copy code
class UserService(
  private val commandService: CommandService,
  private val eventBus: EventBust
) {
  fun createUser() {
    commandService.execute(CreateUser(...))
    eventBus.publish(UserCreated(...))
  }
n
@jbnizet while i’m not a proponent of aop your reasoning and example are actually wrong in a test spring context i’ll contribute a mock repository bean so that it will be the one injected into my entity
m
@Jukka Siivonen @Czar Check out Spring-Data-JDBC. It is attempting to allow DDD using Spring, while providing the mapping portion of ORM. This presentation was at SpringOne Platform 2019.

https://www.youtube.com/watch?v=GOSW911Ox6s&amp;t=124s

I've used it, and it works VERY nicely with Kotlin. Greatly simplifies domain classes as it understands data classes. Worth checking out.
t
it is very opinionated though (for instance, no n-to-n relations as there is no aggregate root by definition in such a relation (I think I read it somewhere in the official docs and/or in an older talk). Thanks for the link btw, I will have a look at it and see if I can give it a second try (I like the jdbc idea so much more than jpa, but in v1.0 there were missing features)
m
Yes, it's very opinionated, so therefore not for every case. If it fits your case, it's very elegant and clean, w/o all the 'magic' of JPA. JPA is also amazing for its use cases. I don't think it will ever support n-to-n relations in the framework. If you have that, and want it managed by the framework, then JPA is your choice. It sounded intentional after listening to the talk.
j
@nfrankel if you have a test spring context, it’s not a unit test anymore.
n
agreed but you never mentioned it would need to be 😉
j
Say you create a mock repository and inject it into a service that you want to unit-test.
👍 1
n
ok 🙂
let’s say it was not obvious 👇
And it makes the code impossible to test
👍 1