在共享库中为 JPA 实体(域类型对象)创建基础 class 的缺点
Drawbacks of creating base class for JPA Entity(domain type object) in a shared library
我是一名经验丰富的 .net 开发人员,最近转向 java 开发。我正在使用 spring boot/cloud 开发微服务。对于我的工作,我创建了一个公共 jar(共享库),我在其中放置了那些将在不同的微服务中重用的功能和辅助方法。
我在我的每个 spring 引导微服务应用程序中调用共享库,方法是添加它们的 pom file.This 一切正常,我可以在我的每一个微服务都如愿以偿。
现在..
我正在使用 JPA 来保存数据,因此每个微服务应用程序都需要有一个实体 class,它使用代码优先的方式在各自的数据存储中创建持久性。
由于大多数微服务中需要的公共字段很少,我想到了在我的公共 jar(共享库)中创建一个基础实体 class 并使我的微服务中的实体继承基础的想法实体 class.
这是我在共享库中创建的基础实体class
package com.microservice.xcloud.common.entity;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
@MappedSuperclass
public class BaseEntity {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
Long id;
...
@Column(nullable = true , name = "isDeleted")
private boolean isDeleted;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
...
public boolean isDeleted() {
return isDeleted;
}
public void setDeleted(boolean isDeleted) {
this.isDeleted = isDeleted;
}
}
现在在我不同的微服务中,我继承了这个 class 以便拥有这些字段而无需一次又一次地编写它们。(DRY 原则) .
我在使用 .net 和 EF 时也使用过这种方式,发现它工作得非常好。我会将基本实体放在一个共享的 dll 中,并在我的应用程序中继承它。
所以我虽然对 java 使用了相同的东西,但我在我的微服务应用程序的实体 class.
中做到了这一点
package com.microservice.xcloud.companyservice.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import com.microservice.xcloud.common.entity.BaseEntity;
@Entity
@Table(name = "companymaster")
public class CompanyMaster extends BaseEntity{
@Column(nullable = false , name = "companyName")
private String companyName;
@Column(nullable = true , name = "description")
private String description;
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public CompanyMaster() {
super();
}
}
请注意,我有两个不同的应用程序,
1. 共享 java 库称为 common
2.通过pom
使用共享库调用company-service的微服务应用
<!-- Shared library -->
<dependency>
<groupId>com.microservice.xcloud</groupId>
<artifactId>common</artifactId>
<version>${project.version}</version>
</dependency>
有人告诉我这是一个糟糕的架构,不应该这样做。我还被告知,这将导致对 db 的两次单独调用,一次用于共享库的基础实体,另一次用于微服务的实体 class。这是我在 .net 世界中从未听说过的事情。由于我是 java 的新手,因此我需要您的专家建议。
据我所知,在 .net 世界中,由于共享库是一个 dll,它不能单独 运行 并且需要附加到应用程序,这是完全不可能的。
我的共享库(使用 spring 引导创建)没有主要方法,因此应该附加到调用微服务,就像附加到 exe 类型的 jar 的 dll 类型 jar。
感谢您的专业知识和亲切的关注
我没有看到任何问题,因为您的实体没有任何可以导航到其他实体的字段(即没有映射到 @OneToMany
/ @ManyToOne
的字段),所以它的所有字段都映射到同一个数据库 table 并且没有理由会导致单独的数据库调用来加载实体。
spring-data-jpa also provides a base entity AbstractAuditable
开发者可以选择使用它而不是自己创建(虽然使用它会增加实体与 Spring 数据的耦合),因此将基础实体作为单独共享 JAR 并让其他项目使用是很常见的。如果您的公司有一些规则,所有实体都必须具有特定的字段集,如 id 、 createdBy 等,这甚至是一个很好的做法,主要是因为它可以像您所说的那样使代码变干。
我是一名经验丰富的 .net 开发人员,最近转向 java 开发。我正在使用 spring boot/cloud 开发微服务。对于我的工作,我创建了一个公共 jar(共享库),我在其中放置了那些将在不同的微服务中重用的功能和辅助方法。
我在我的每个 spring 引导微服务应用程序中调用共享库,方法是添加它们的 pom file.This 一切正常,我可以在我的每一个微服务都如愿以偿。
现在.. 我正在使用 JPA 来保存数据,因此每个微服务应用程序都需要有一个实体 class,它使用代码优先的方式在各自的数据存储中创建持久性。
由于大多数微服务中需要的公共字段很少,我想到了在我的公共 jar(共享库)中创建一个基础实体 class 并使我的微服务中的实体继承基础的想法实体 class.
这是我在共享库中创建的基础实体class
package com.microservice.xcloud.common.entity;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
@MappedSuperclass
public class BaseEntity {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
Long id;
...
@Column(nullable = true , name = "isDeleted")
private boolean isDeleted;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
...
public boolean isDeleted() {
return isDeleted;
}
public void setDeleted(boolean isDeleted) {
this.isDeleted = isDeleted;
}
}
现在在我不同的微服务中,我继承了这个 class 以便拥有这些字段而无需一次又一次地编写它们。(DRY 原则) .
我在使用 .net 和 EF 时也使用过这种方式,发现它工作得非常好。我会将基本实体放在一个共享的 dll 中,并在我的应用程序中继承它。 所以我虽然对 java 使用了相同的东西,但我在我的微服务应用程序的实体 class.
中做到了这一点package com.microservice.xcloud.companyservice.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import com.microservice.xcloud.common.entity.BaseEntity;
@Entity
@Table(name = "companymaster")
public class CompanyMaster extends BaseEntity{
@Column(nullable = false , name = "companyName")
private String companyName;
@Column(nullable = true , name = "description")
private String description;
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public CompanyMaster() {
super();
}
}
请注意,我有两个不同的应用程序, 1. 共享 java 库称为 common 2.通过pom
使用共享库调用company-service的微服务应用<!-- Shared library -->
<dependency>
<groupId>com.microservice.xcloud</groupId>
<artifactId>common</artifactId>
<version>${project.version}</version>
</dependency>
有人告诉我这是一个糟糕的架构,不应该这样做。我还被告知,这将导致对 db 的两次单独调用,一次用于共享库的基础实体,另一次用于微服务的实体 class。这是我在 .net 世界中从未听说过的事情。由于我是 java 的新手,因此我需要您的专家建议。 据我所知,在 .net 世界中,由于共享库是一个 dll,它不能单独 运行 并且需要附加到应用程序,这是完全不可能的。 我的共享库(使用 spring 引导创建)没有主要方法,因此应该附加到调用微服务,就像附加到 exe 类型的 jar 的 dll 类型 jar。
感谢您的专业知识和亲切的关注
我没有看到任何问题,因为您的实体没有任何可以导航到其他实体的字段(即没有映射到 @OneToMany
/ @ManyToOne
的字段),所以它的所有字段都映射到同一个数据库 table 并且没有理由会导致单独的数据库调用来加载实体。
spring-data-jpa also provides a base entity AbstractAuditable
开发者可以选择使用它而不是自己创建(虽然使用它会增加实体与 Spring 数据的耦合),因此将基础实体作为单独共享 JAR 并让其他项目使用是很常见的。如果您的公司有一些规则,所有实体都必须具有特定的字段集,如 id 、 createdBy 等,这甚至是一个很好的做法,主要是因为它可以像您所说的那样使代码变干。