0:18 okay um welcome to my talk and uh thanks
0:21 for having me in
0:24 Barcelona um looks like a really nice
0:25 place to
0:28 visit um guess I should have brought a
0:31 little more time but anyway at least the
0:33 view outside the windows is
0:38 nice I'm going to talk about how to
0:40 migrate from Spring data jpa to Spring
0:43 data jdbc I guess that is not a surprise
0:46 for you although I do have a couple of
0:49 questions like the first question is who
0:52 actually read the
0:55 abstract okay and nobody thought it
0:57 might be worth telling someone that it's
1:00 totally bogus for those that didn't read
1:03 the abstract uh it's actually what
1:05 should have gone under my or into my
1:08 speaker bio something got mixed up there
1:12 but I guess the title kind of speaks of
1:16 itself more questions um I would like to
1:22 understand who I'm talking to who likes
1:26 jpa quite a few hands okay there's no
1:34 who of you have actually used spring
1:37 data jdbc at least in like a little toy
1:40 project a demo most of you that's good
1:43 because I try not to explain too much
1:46 about spring data jdbc
1:50 itself but who has used it in
1:53 production that are I'd say a little
1:55 more than the people that actually like
2:00 jpa so that's that's good although the a
2:02 might be
2:05 biased and who is actually migrating or considering
2:08 considering
2:17 hands honest question why no no really
2:21 like you're doing a big change to your
2:28 migrate
2:30 pdon come I get a little louder
2:33 more control more
2:36 control I I think that's in general a
2:40 valid valid reason
2:43 um but we'll see like how you think
2:46 about these reasons after the talk um to
2:50 be very clear I created spring data jdbc
2:54 I love it I consider it my third child but
2:55 but
2:59 um as with the other two Childs and
3:01 everybody that is is honest about his or
3:05 her child Childs aren't perfect
3:09 and also just
3:13 replacing someone with your own child um
3:19 easy before we start with the actual
3:23 migration we have to like settle down
3:25 some some foundations
3:27 foundations
3:32 um we are doing a talk of 50 minutes
3:35 well actually I guess I lost two minutes
3:38 um for a late start um but all this has
3:40 to be considered in the context of a
3:44 serious project like I have a little Deo
3:48 demo project that I use to to go through
3:51 this process myself um that's basically
3:54 it plus a little demo service that
3:56 actually uses this domain model and the
3:59 repositories your projects are probably
4:03 much bigger or if you have some serious
4:06 micro uh projects or microservices they
4:09 might like a single service might look
4:11 like that but then you probably have
4:16 dozens of it so whatever I show you here
4:17 or what I
4:20 discuss um yeah that looks easy for a
4:24 small project but remember in a serious
4:28 context you might have to do that dozens
4:30 maybe hundreds in some some cases
4:37 times and partly for that reason before
4:40 you start any kind of migration doesn't
4:44 matter what you migrate from or to you
4:47 don't start before you have a serious
4:49 set of
4:53 tests so test question who is
4:55 comfortable to like replace your persistence
4:57 persistence
5:02 layer and be sufficiently secure that if
5:05 there's something fatally wrong with a
5:07 persistence layer your test will tell
5:09 you hands
5:13 up okay great to see that there are many
5:16 hands up um for all others you know what
5:27 first and then there's something very
5:30 well really not very technical
5:32 walk with baby steps that's that's a
5:35 term I learned at a conference like I
5:39 don't know uh 10 years ago and the
5:42 meaning is do really really small
5:46 steps actually try doing incredibly
5:50 small uh steps because the problem is
5:53 that you easy get to in really in any
5:55 kind of development but especially with
5:57 refactorings is you think like I'm going
6:00 to solve this little problem and do a
6:02 code change and then you notice oh no
6:05 something over here is broken I'm going
6:07 to fix that oh now three things over
6:09 here are broken am I going to start to
6:12 fix those um then suddenly all my
6:15 project is readed um two weeks have
6:17 passed uh since the last time my code
6:20 compiled let alone all my tests run
6:22 that's not a good state to be in because
6:26 now you have no idea how much time you
6:28 need until you actually get back to a
6:33 stab uh state so always try to make the
6:35 smallest possible
6:38 change run all your
6:41 tests and commit and we can do that
6:44 nowadays I'm an old guy I remember stuff
6:50 like ACS CVS and srn I think um where
6:54 doing a commit was lengthy operation and
6:57 well if it worked at all nowadays we can
7:00 do that in like it's just
7:03 in the in the Shell One Step Up in the
7:06 history and return and basically a
7:08 no-brain use that
7:09 that
7:13 and even go one step further use the
7:16 Mikado method who knows the Mikado
7:22 method yeah I was afraid of that um it's
7:26 a it's a great tool I'm not going to
7:28 into much detail the basic idea is you
7:30 have a big ref factoring that you want
7:35 to achieve and you start by taking a
7:37 probably big piece of
7:40 paper and writing that goal on that
7:42 piece of paper and making a circle around
7:43 around
7:47 it then you think about like what could
7:52 the first small step be to get to that
7:55 goal and before you hit your keyboard
7:59 you write that little step on your PC of
8:02 paper make a circle around it and draw
8:04 an arrow from the first circle to the
8:07 second this arrow means to reach this
8:10 goal I have to do this other thing and
8:11 then you actually try to do the other
8:14 thing and then we are back to baby steps
8:17 does it work does it compile do all your
8:19 tests pass if
8:23 yes great you can cross out that circle
8:26 on your on your little diagram and find
8:30 the next baby step
8:33 but more likely it doesn't work
8:38 something turns red a test the compiler
8:41 complains this teaches you something it
8:43 shows you a place where you need to
8:46 change something first before you can do
8:48 the thing that you try to do so what you
8:51 do is you draw a new circle on your
8:52 piece of
8:55 paper and again connect the second
8:57 circle to the third circle with an arrow
9:00 knowing okay now I have to
9:03 do this other thing before I can do this
9:06 thing and then comes the really really
9:09 important step of the Mikado
9:13 method you undo your
9:15 changes and then from all the circles
9:17 that don't have any dependencies yet in
9:20 my little examples there's only one
9:23 Circle you try that one and maybe you
9:24 find more
9:27 circles there are two benefits to this
9:29 approach one is
9:33 you're doing baby steps like every few
9:35 minutes you're back to a stable code
9:39 base that you can commit that you can
9:41 merge with your main branch or merge the
9:43 main branch into you or rebase or
9:45 however you want to work with
9:48 that and you have a good visual
9:51 representation of what you still have to
9:55 do and if you plan like two weeks for
9:58 refactoring and after one
10:01 week you your graph hardly fix fits on
10:03 the biggest whiteboard on your office
10:06 and is still growing you know this is
10:09 not going to work in two weeks and that
10:11 is important information that you can
10:18 on so all this was pretty much technology
10:23 independent but there's one thing that
10:25 comes from Spring data jdbc itself
10:27 spring data jdbc is strongly based on
10:29 the concepts of aggregates
10:32 from domain driven design who is
10:34 familiar with the concept of Aggregates
10:36 Aggregates
10:41 okay more than the Mado method still not
10:44 enough Aggregates are again a concept
10:46 from domain driven design and an
10:49 aggregate is basically a bunch of
10:53 classes typically not very many many
10:55 Aggregates are a single class sometimes
10:58 they are two classes if you have an
11:01 aggregate that con P consists of five
11:03 classes it's probably too
11:06 big and the important thing about an
11:09 aggregate is
11:13 twofold it is always transactionally
11:16 consistent so whatever you do to an
11:19 aggregate you always do it all or
11:23 nothing and the other thing is whatever
11:26 is inside the aggregate only gets
11:28 controlled by the so-called aggregate
11:31 route which is the single class that
11:33 knows about all the others and if you
11:36 want to manipulate them uh these inner
11:38 classes you always do that through the aggregate
11:39 aggregate
11:43 route and spring data jdbc uses that in
11:46 a very important
11:48 way um the
11:51 aggregate is the unit that spring data
11:54 jdbc uses for persisting and loading
11:58 data in jpa you have all this cascading
12:00 and different fetch
12:04 strategies and if you aren't careful you
12:07 um trigger different selects when you
12:10 just access a geta or you load the whole
12:13 database into memory just when you load
12:17 one little entity um this is very
12:20 obviously obvious in Spring data
12:23 jdbc if you load an
12:26 aggregate it will load everything that
12:28 is referenced by that aggregate by
12:30 normal Java reference
12:33 refence if and the boundaries of the
12:35 Aggregates are actually defined by well
12:38 not using references anymore instead you
12:40 basically use an ID to reference a different
12:42 different
12:46 Aggregate and like understanding these
12:48 Aggregates is really important at the
12:52 end of the slides um I have a link to a
12:55 little article I wrote um you can read
12:57 up on that um that's a really important concept
13:03 and then there's one final thing you
13:05 have to think about or you probably
13:08 should think about before starting your
13:11 migration project is do you want to go
13:14 breadth first or depth first basically
13:17 the steps that I'm going to show you you
13:20 have to apply them to basically every
13:21 aggregate in your
13:24 project if you want to do a complete
13:27 migration and it's probably like if you
13:30 look at the total time you used it's
13:33 probably faster if you do the same step
13:35 for all the Aggregates that are out
13:37 there because then you're like in the
13:39 process okay I know this I have to do
13:41 this kind of stuff and then you just do
13:44 it over and over and over which might
13:46 become boring but very efficient but
13:49 then you have a lot of Aggregates like
13:51 in the middle of a
13:54 migration if there is a chance that you
13:56 don't migrate the whole project I would
14:00 recom recommend go depth first meaning
14:04 pick an aggregate completely migrated or
14:07 migrated as far as you want to and then
14:14 aggregate
14:16 so let's get
14:18 started what do you think should be the
14:21 first thing to do when migrating a
14:25 project from jpa or spring data jpa to
14:36 run your chest well yeah okay good point
14:37 I don't have that on the
14:43 slides um no but specific to the
14:45 migration what ia did I just talked about
14:47 about
14:49 Aggregates and the
14:53 problem is spring data really always is
14:56 based on Aggregates but jpa kind of
15:00 breaks that and also for many
15:02 stores it's not that important
15:05 especially jpa it's like nothing bad
15:07 happens if you ignore that at least not
15:10 in the short run so what you have to do
15:13 is actually identify your
15:15 Aggregates and for those that know how
15:19 Aggregates work in this diagram what do
15:31 yeah almost actually all the light green
15:33 boxes are
15:38 entities and the dark greens are the
15:40 repositories and in many
15:43 cases the entities and Aggregates are
15:46 actually identical but there's one case
15:49 where this isn't the case in this
15:57 shipment the the thought process here is
16:00 like can these things exist
16:03 exist
16:05 independently I can imagine a shipment
16:07 that doesn't have a
16:09 customer I can't really ship that
16:12 probably but I can do a lot of things
16:15 that I can validate it I can I can start
16:17 picking that stuff I can't just really
16:21 ship it
16:25 um but the relationship between shipment
16:29 and the items inside the shipment
16:31 that's like a shipment without any items
16:36 is kind of useless and items that don't
16:38 belong to a shipment what is even the
16:42 meaning of that so these are probably um
16:44 one one
16:47 Aggregate and um that's something I have
16:51 to to First realize for the next step
16:53 which is remove all the extra
16:57 repositories that you most likely if you
16:59 never thought about aggregates have in
17:01 your code base
17:03 base
17:05 because again I
17:09 said um an aggregate should be handled
17:13 as one unit should be persisted as
17:16 one so it doesn't make sense to have a
17:19 repository for an entity that is inside an
17:20 an
17:23 aggregate so we have a Superfluous
17:25 repository here which is the item
17:28 repository that needs to go away and
17:30 that of course it's easy in a diagram
17:36 like this um in code um that's also easy
17:38 um we just delete it if you don't notice
17:42 this has like light greenish hint which
17:46 is the in my configurations of intellig
17:48 um how it displays like this thing is
17:51 gone in this commit but of course if I
17:55 have that repository I probably used it
17:57 um so I need to change some places in my
17:59 code um
18:03 um in this case um I have this uh
18:06 service method they don't make too much
18:08 sense they are really created just to to
18:11 demonstrate the kind of issues um you
18:15 will find in your code um it accesses
18:18 directly um an item by ID and then
18:21 changes the quantity and now I have to
18:24 access that item in a different way and
18:27 again I said in the beginning about
18:29 Aggregates everything inside an
18:32 aggregate gets only accessed through the
18:35 aggregate route and I do in this little
18:38 code change the kind of a minimal
18:41 version of that I still access it from
18:45 the outside but at least I load the um
18:48 the shipment and then find inside the
18:50 shipment the correct item and then
18:55 manipulate it if I want to do the full
18:58 thing um like in the real beautiful
19:01 domain driven design uh style all this
19:04 logic should actually go into the
19:08 shipment class but that is kind of not
19:10 necessary for the migration so you can
19:13 do that whenever it fits you and it
19:18 doesn't really appear um in the
19:26 change because you now use a method in
19:28 the item um no in the shipment repos
19:30 repository that wasn't there before yet
19:33 so you have to create that method which
19:38 in this case is a simpler simple find uh
19:41 method that you can just add it might
19:43 actually mean that you have to write
19:45 custom SQL or
19:51 jpql um whatever it uh it might involve
19:54 that depends obviously heavily on your
19:57 project and I can't really do much of an
19:59 advice here
20:02 but this is a good uh place to to like
20:06 revisit the Mikado method because with a
20:08 Mikado method I would actually do this
20:11 kind of in the reverse order I would
20:15 start okay I just delete the item
20:18 repository then notice oh that doesn't
20:20 work I first have to get rid of this
20:24 invo invocation of the item method then
20:26 when I tried to do that I noticed well I
20:28 need need a new method in the sh shipment
20:29 shipment
20:32 repository again undo all my
20:34 changes implement the method for the
20:38 shipment repositories with tests
20:42 obviously then um refector this method
20:46 to use only that and no longer the item
20:49 repository and then the final step is I
20:51 can actually delete the item
20:53 repository and does that sound
20:57 complicated and kind of convoluted yes
20:59 it does but if you work work with a code
21:02 base with dozens of or hundreds of
21:06 entities that might exist already for 10
21:09 or 20 years long before you Jo uh joined the
21:10 the
21:23 me the next thing to do is make all the
21:25 safe statements
21:29 explicit jpa has this great feat feure
21:31 or I should say
21:36 feature that it POS it saves everything
21:40 in the um in the persistence
21:43 context and that can create funny
21:47 results sometimes if you're not aware of
21:52 that and it um often um uh results in
21:54 the effect that calling the safe method
21:57 of a jpa repository isn't really necessary
22:00 necessary
22:05 one example is here um in this
22:09 example I load a product and then manipulate
22:10 manipulate it
22:12 it
22:14 and then
22:18 nothing but all this runs inside a
22:22 transaction so jpa
22:25 automatically possess all this stuff
22:27 spring data jdbc will not do that for you
22:29 you
22:32 if you load an enti with spring data
22:35 jdbc it's totally disconnected from
22:38 Spring data jdbc it's just a plain class
22:42 nothing special about it not a proxy
22:44 just the class how you implemented it
22:46 and it has no way of knowing that you
22:48 actually change the data and might want
22:52 to persist that so you have to add a safe
22:53 safe
22:58 method there are other cases um
23:02 where uh this happens which is when when
23:06 you have Cascade annotations in this
23:09 example I have a shipment and I might
23:12 create a customer and then at the end I
23:15 only save the shipment but the customer
23:19 that I created here gets again due to
23:22 some um Cascade
23:24 annotations on the
23:27 shipment gets persisted as well in order
23:29 to make this work
23:31 properly when we finally switch to
23:35 Spring data jdbc we have to actually add
23:39 a save um call over there can you
23:41 actually see the colors of the diff like
23:50 color kind of I'm not able to change it
23:53 sorry lesson learned for
23:56 me once you have done
23:59 that you can actually get rid of all the
24:04 Cascade data in your repositories that
24:07 crosses Aggregates because again
24:10 Aggregates are kind of
24:12 autonomous if you have if you work on
24:15 two Aggregates at the same times domain
24:17 driven design
24:19 hardcores might actually consider that a
24:22 smell in the first place but at
24:27 least you you shouldn't cause saving one
24:31 aggregate to um have an A another
24:34 aggregate saved as well that's basically
24:41 no once you're here the next step I
24:44 would propose is
24:46 simplifying our
24:49 references in jpa it's very common to
24:52 have bidirectional references meaning
24:55 you have two classes A and B and a
24:58 references B and B references a and and
25:02 they are basically the same
25:05 relationship and spring data
25:09 jdbc can't do that which might be a
25:12 surprise if you get started with it but
25:15 the fun thing is it doesn't need
25:17 it you'll see
25:21 why so if you look at our um little
25:24 diagram again there are multiple places
25:26 where we have these bir directional
25:28 references and for each each one of
25:31 those we now need to decide like which
25:33 direction should they really
25:36 go first one customer to
25:40 shipment and like one thing that can help
25:41 help
25:45 deciding um which direction you should keep
25:47 keep
25:50 is what should come first that's the one
25:51 that gets
25:54 referenced and normally you first have a
25:55 customer before you try to ship
25:58 something to them so
26:00 the shipment should reference the
26:02 customer not the other way
26:06 around the next case is within
26:08 Aggregates there the rule is really
26:11 simple reference always go from the root
26:15 to the entities contained in the
26:18 aggregate because again we always
26:20 reference the root in the first place so
26:22 what other way would be to to reach all
26:24 the internal
26:29 stuff and in product and category
26:33 I guess one could it do both sides
26:37 like but having categories reference
26:39 products kind of feels weird to me I'm
26:42 honest I'm not able to formulate a hard
26:45 rule at this place but I think product
26:55 go and in code this can be as simple as
26:57 removing the reference but then again
26:59 you all of course have in a real world
27:02 scenario tons of places where you
27:04 reference or where you use that
27:07 reference and for those you have
27:10 basically a similar process as with a item
27:11 item
27:15 repository um you need new repository
27:21 methods for that so if somebody used to
27:24 like this this thing comes from the from
27:27 the customer if there was a code uh
27:29 place where some somebody navigated from
27:32 customer to shipment you now have to
27:35 call the shipment repository and say
27:42 customer new method and use the Mado
27:44 method same
27:47 process it gets a little more
27:50 complicated for m2n joints or m2n
27:53 relation tables
27:59 um jpa normally hides them from you
28:01 like in this
28:03 diagram there is actually an m to n
28:06 relationship um you might be able to
28:09 guess products can belong to multiple
28:12 categories and of course each category
28:14 probably has multiple products that
28:18 belong to it so in your database schema
28:21 there is this join table in between but
28:24 it doesn't appear in your entity classes
28:26 spring data
28:31 jdbc needs the needs this class
28:35 explicitly and so now you have another
28:37 aggregate that actually consists of two
28:40 classes and again in code the first part
28:44 is well you need this um reference
28:47 entity this joining entity which
28:50 basically oh you can't see my pointer
28:53 here which really just cons consists of
28:56 two references marked as ID and all The
28:59 jpa annotation to have the the right
29:05 everything and of course everywhere
29:09 where I use this I now have to use this
29:19 category once I'm at this place I have
29:23 only one: M or M to n relationships and
29:26 they are all non
29:29 bidirectional and at this this place I
29:33 now can change all these references across
29:34 across
29:48 model all the reference that cross aggregate
29:50 aggregate
29:53 boundaries that are
29:56 these kind of dissolve they are
29:59 semantically there
30:02 but they are not Java references anymore
30:06 instead of a customer I'm going to uh
30:11 ID so this
30:16 is exactly what happens in this case um
30:19 for the item that happens uh reference
30:24 the product it now references a product ID
30:26 ID
30:29 and the this might feel like a
30:32 degradation in in kind of usability of
30:34 your domain
30:38 model but really it gives you a clear
30:42 structure it defines your Aggregates now really
30:49 and and these are boundaries where your
30:52 application kind of breaks into little
30:55 pieces like a bar of chocolate and the
30:58 keyn note this morning we heard about modular
31:00 modular
31:04 modulus this is exactly one tool to to
31:08 break these apart to have to not have a
31:14 huge um modulith that has no clear
31:18 structure but well a clear structure
31:21 where you can can move pieces around and
31:22 we did all
31:26 this without using spring data jdbc in
31:28 any way
31:31 so you can do this or parts of this in
31:35 your jpa project and decide not to use
31:36 spring data
31:39 jdbc and at least in my
31:43 opinion it improves your source code the
31:45 maintainability the understandability
31:53 boundaries but of course we are here and
31:55 actually want to migrate to Spring data
31:59 jdbc so first thing
32:01 actually added to your project as a
32:04 dependency and I guess most of you are
32:07 using spring boot nowadays and that
32:11 means you just add the spring boot
32:13 starter for spring data
32:18 jdbc and um that's it it like in a
32:20 simple project it will pick up the data
32:24 source and use it and live right next to
32:31 of course if you have a more complex
32:34 setup maybe multiple data sources or fun
32:37 stuff like that of course your setup for
32:39 spring data jtbc will be more
32:48 well one thing you probably have to do
32:50 is you have to
32:54 create an idea generator one or
32:58 multiple in my little project I used
33:01 um well when I when I set up the project
33:04 I really used the simple stuff that I um
33:06 could think of while making all the
33:10 stuff that I consider not so smart um so
33:13 I have something to show you and um it
33:17 turned out um jpa used
33:19 sequences but spring data jdbc by
33:21 default expects that the
33:25 database will um create the ID and
33:27 return it when I insert
33:31 um a data set if I don't have that I
33:31 have to
33:35 explicitly generate an ID in a listener
33:38 or basically a
33:42 um a call back uh before convert call
33:48 back that has a simple method it
33:51 gets um one entity of the type that is
33:54 given up there you can use object then
33:55 you have to check what kind of entity
33:58 you have inside the method and it just
34:03 checks is this uh does this have a null
34:08 ID if that is the case it obtains in an
34:13 ID using just a jdbc template and sets
34:15 the ID if you want to use different
34:17 strategies to create
34:21 IDs feel free same same
34:25 principle and um do whatever you want
34:27 and if you do something interesting
34:35 project the next thing you probably have
34:39 to do in a real world project is write a
34:40 bunch of
34:43 converters there's like all the the
34:46 basic data types get um persisted and
34:48 loaded just fine but if you have more
34:50 complex stuff you have to write
34:53 converters I didn't present a converter
34:56 because well converter again basically
34:59 two methods one converting from your
35:01 domain type to whatever is persistable
35:03 in the database the other one converting
35:07 it back um I'm not saying that it's it's
35:10 trivial or not much work but there's
35:15 you
35:19 and once you have those that you need
35:22 for all your Aggregates you can take an
35:26 Aggregate and then actually convert it
35:28 like replace all the map
35:34 information from jpa to Spring data
35:37 jdbc and that's the one thing that you
35:39 can't really break down into smaller
35:41 steps because you
35:44 can't I guess it's obviously not have an
35:48 entity that is 50% jpa and 50% spring
35:51 data jdbc I can't even imagine how that
35:56 is would be supposed to work and um an
35:58 important thing is
36:02 um unfold your import statements because
36:06 there are quite some uh
36:09 annotations that exist in both worlds
36:12 like jpa has a table
36:15 annotation and um jpa and spring data
36:17 jdbc both have an ID
36:20 annotation and um another example is the
36:24 query annotation exists for both uh
36:27 modules but are different classes and
36:30 you have to replace one with the other
36:33 and there is still a lot of work you
36:36 probably have to create custom
36:40 cruies um uh spring data jpa is more
36:45 feature especially um regarding Cy Generation
36:46 Generation
36:51 Um but yeah there's like this is the
36:53 part where I only have a few slides
36:55 doesn't mean there's a little work for
37:10 work I don't know if that is a surprise
37:12 or if anybody came here and thought like
37:15 well they I'm sure they have like some
37:20 AI thing generating open rewrite recipes
37:22 um it's something I'm thinking about but
37:26 um didn't get beyond the thinking about
37:32 a lot of that work can be broken down
37:35 into small steps which is a good thing
37:37 and an important thing don't try to do
37:42 everything at once that won't work and
37:44 can cost you a lot of time and time is
37:46 money quite
37:50 literally most of the stuff is
37:53 untangling structures that we are kind
37:56 of they are not really caused by jpa
37:59 because I just demonstrated you can undo
38:03 them while staying well within jpa world
38:09 but jpa allows them to do that and I
38:11 think that's an
38:14 architectural Choice possibly
38:18 mistake um Fielding described
38:21 architecture as the decision like what
38:25 not to do and jpa in that sense comes
38:28 with very little architecture jpa
38:31 basically says yeah give me your model
38:33 give me your schema and one way or the
38:35 other I'm mapping one to the other
38:39 spring data jdbc is way more strict in
38:43 that regard it says I have a way to map
38:45 a model to the database and yes you of
38:48 course you can tweak things like table
38:49 and column names and stuff and you can add
38:50 add
38:55 converters but there's a very
38:58 strong I'd say ccept set that have to
39:02 fit in and it gives the application a
39:05 nice clean upright posture that is nice
39:07 to look
39:11 at so if all that is too much work for
39:13 you and you think like okay making my
39:16 application easier to understand is it
39:20 worth all that work maybe you have a a
39:23 big application with 100
39:26 entities and in the last two years
39:28 you're really only working with this
39:31 cluster of 12
39:36 entities um well you can decide to only
39:39 use spring data jtbc for new stuff you
39:42 can say okay whenever we touch something
39:44 then we are going to migrate it to
39:45 Spring data
39:50 jdbc um the two can exist in the same
39:53 project and I'm not going to say without
39:56 problem I'd say without problem from the
39:59 spring data jdbc design because
40:01 jpa has
40:04 some has some problems if you actually
40:07 use SQL against the database but again
40:09 we are separating our application first
40:13 into Aggregates and then decide okay I
40:15 going to use spring data jdbc for this
40:17 Aggregate and spring data for jpa for
40:21 this Aggregate and that should work fine
40:29 I promised a couple of
40:33 links and some I didn't promise all the
40:36 the screenshots of the code uh in this
40:39 GitHub repository there are actually two
40:41 branches like the main branch and
40:44 basically a branch further below you can
40:47 say as basically set up at this Branch
40:51 okay I have a working jpa application
40:54 and then in small steps I went up until
40:56 I have migrated everything to Spring
40:58 data jdbc
41:01 um you can play with
41:04 that then I mentioned the Mado method a
41:07 couple of times if you do any kind of
41:09 refactorings no matter if related to
41:15 Spring data jdbc or not do yourself um a
41:17 favor and get this book and read through
41:20 it I have actually never read the book
41:23 but I read it when it still was a PDF
41:27 and available for free um You probably
41:29 have to to pay a few bucks but you're
41:31 software developers I think you can you
41:33 will be able to pay for
41:36 that and um for those that are really
41:39 new to Spring data jdbc there's an
41:41 article where I try to explain this
41:45 Aggregates and reference stuff um that's
41:47 probably helpful in
41:50 understanding why we did all these
41:53 things that I just explained
41:54 explained
41:59 and with that I'm done and open for
42:01 questions if you want [Applause]