在共享库中为 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 并且没有理由会导致单独的数据库调用来加载实体。

also provides a base entity AbstractAuditable 开发者可以选择使用它而不是自己创建(虽然使用它会增加实体与 Spring 数据的耦合),因此将基础实体作为单独共享 JAR 并让其他项目使用是很常见的。如果您的公司有一些规则,所有实体都必须具有特定的字段集,如 id 、 createdBy 等,这甚至是一个很好的做法,主要是因为它可以像您所说的那样使代码变干。