spring-data-jpa 如何在多个Sping Boot 应用程序之间共享JPA实体

r3i60tvu  于 2022-11-10  发布在  Spring
关注(0)|答案(2)|浏览(122)

我们希望在公开为微服务的两个应用程序之间共享Employee。但是Employee具有JPA定义,我们如何将其打包为可在多个应用程序之间共享的单独jar

Spring Boot “AppA”具有以下实体

@Entity
@Table (name = "employees")
public class Employee {

}

Sping Boot “AppB”从“AppA”获取员工

ResponseEntity<Employee[]> response =
  restTemplate.getForEntity(
  "http://localhost:8080/employees/",
  Employee[].class);
Employee[] employees = response.getBody();
jei2mxaa

jei2mxaa1#

您必须先将实体 Package 在Record中,然后使用Corba-SCNR版本3从其他服务访问它。
或者,您可能需要重新考虑微服务体系结构,因为让两个服务访问同一个实体/数据库是不好的。
好了,拖钓时间结束了。
要回答您的问题:您不能以JPA/Hibernate定义的保证方式在两个服务之间共享REST上的实体。为什么会这样呢?因为JPA/Hibernate中的EntityManager创建了一个围绕Java对象的 Package 器,拦截对它的调用,并在某种程度上记住您更改某些字段的时间,以便在您将更改“刷新”到数据库时,它知道要生成哪些SQL语句。这些 Package 器不能在REST端点上序列化,至少不能以另一个服务可以拾取它们并在第一个服务停止的地方继续的方式序列化。
一般来说,直接在REST控制器中公开JPA实体是个坏主意。我个人更喜欢创建小的DTO(数据传输对象),用我需要公开的数据填充这些DTO,并且只在REST端点中公开那些DTO。
因此,最好考虑“AppB需要Employee提供哪些信息”,并将这些信息放在DTO中,然后在AppA的Controller中公开它们。如果需要对AppB中的Employee进行更改,请在AppA中创建一个接受来自AppB的请求的Controller,然后将请求从AppB发送到AppA。
根据您创建的EmployeeDTO的大小,您可以将其放入一个共享的jar中,或者简单地将其复制过来。根据您的项目的大小,您也可以在AppA中的Swagger/OpenAPI中描述它,然后在AppB中生成它,但这可能有点矫枉过正。
我希望这能帮上点忙。抱歉之前的诽谤。

7vhp5slm

7vhp5slm2#

如果您确实需要共享它们,而不想复制和粘贴,您可以通过将共享实体和repos打包到一个单独的Spring项目(没有www.example.com)上Application.java,并在下游服务中将该项目声明为maven/gradle依赖项来实现。
假设您已经将实体和存储库放在以下包下的一个单独的库中:在类似于 my.common.lib.entitiesmy.common.lib.repos 的包下
您可以让Spring在下游服务AppA和AppB上发现它们,方法是在相应的Spring应用程序类上使用 @ComponentScan
附录A:

@ComponentScan(basePackages={"my.common.lib.entities", "my.common.lib.repos"})
@SpringBootApplication
ApplicationAppA {

}

相关问题