Reputation: 6110
We would like to share the Employee across both applications exposed as micro services. But Employee has the JPA definition, how do we package this is as a separate jar which can be shared across multiple applications
Spring Boot "AppA" has following entity
@Entity
@Table (name = "employees")
public class Employee {
}
Spring Boot "AppB" fetches Employee from "AppA"
ResponseEntity<Employee[]> response =
restTemplate.getForEntity(
"http://localhost:8080/employees/",
Employee[].class);
Employee[] employees = response.getBody();
Upvotes: 3
Views: 3753
Reputation: 1831
You have to wrap the Entity first in a
Record
and then useCorba-SCNR
version 3 to access it from the other service.Alternatively, you might want to rethink your microservice-architecture, as its not good to have two services access the same entity/database.
Ok, trolling time is over.
To answer your question: you cannot share an Entity over REST between two services in a way that is still giving you the guarantees defined by JPA/Hibernate.
Why is that? Because the EntityManager
in JPA/Hibernate creates a wrapper around the Java Object you have, intercepts calls to it and kind of remembers when you change some fields so it knows which sql statements to generate when you "flush" the changes to the database. These wrappers cannot be serialised over your REST Endpoints, at least not in a way that another service could pick them up and continue where the first service stopped.
In general, it is a bad idea to directly expose your JPA Entities in your REST Controllers. I personally prefer to create small DTOs ( Data Transfer Object ) that I fill with the data that I need to expose and only expose those in the REST endpoints.
So best would be to think about "which information does AppB need from the Employee" and put theses in the DTO, then expose them in the Controller of AppA. If you need to make changes to the Employee in AppB, create a controller in AppA that accepts requests from AppB and then send a request from AppB to AppA.
Depending on the size of the EmployeeDTO
you create, you could put it into a shared jar or simply copy it over. Depending on the size of your project, you could also describe it in Swagger/OpenAPI in AppA and generate it in AppB, but this might be overkill.
I hope this helps a bit. Sorry for the trolling before.
Upvotes: 3
Reputation: 41
If you really need to share them and do not want to copy and paste you can achieve that by packaging your shared entities and repos on a separate Spring project (without an Application.java) and declaring that project in your downstream services as maven/gradle dependency.
Let's say you've put the entities and repos in a separate library under the following packages: Under a package like my.common.lib.entities, my.common.lib.repos
You can make Spring discover them on your downstream services AppA and AppB by using @ComponentScan typically on your corresponding Spring Application classes:
AppA:
@ComponentScan(basePackages={"my.common.lib.entities", "my.common.lib.repos"})
@SpringBootApplication
ApplicationAppA {
}
Upvotes: 4