I'm an experienced .net developer recently shifted to java development. I'm working on micro-service using spring boot/cloud. For my work I have created a common jar(shared library) where I'm placing those functionalities and helper methods which are to be reused across different micro-services.
I'm calling the shared library in my each spring boot micro-service application by adding it their pom file.This is all working great and I'm able to use the shared library in my every micro-service as intended.
Now.. I'm using JPA for saving data and hence each micro-service application requires to have an entity class which is using code first way to create persistence in their respective data store.
Since there are few common fields required in most micro-services I thought the idea of creating a base Entity class in my common jar(shared library) and make entities in my micro-services inherit the base Entity class.
This is the base Entity class that I created in my shared library
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;
}
}
Now in my different micro-services I'm inheriting from this class in order to have those fields without writing them again and again.(DRY princliple).
I've used this way while working with .net and EF also and found it to be working perfectly well. I would place the base entity in a shared dll and inherit from it in my application. So I though of using the same thing for java and I did this in my micro-service application's Entity 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();
}
}
Please note that I have two different applications, 1. Shared java library called common 2. Micro-service application called company-service using the shared library through pom
<!-- Shared library -->
<dependency>
<groupId>com.microservice.xcloud</groupId>
<artifactId>common</artifactId>
<version>${project.version}</version>
</dependency>
I was told that this is a bad architecture and should not be done this way. Also I was told that this would led to two separate calls to db, one for shared library's base entity and another for micro-service's entity class. This is something I never heard about in .net world. Since I'm new to java I need your expert advise. As far as I know , in .net world since a shared library is a dll and it can not run seperately and needs to be attached to the application, this is totally out of question. My shared library(created using spring boot) has no main method and hence should be attached to the calling micro-service like a dll type jar attaching to exe type of jar.
Thanking you for yours expertise and kind attention
I don't see any problems since your entity does not have any fields that can navigate to other entities (i.e does not have field that is mapped with @OneToMany
/ @ManyToOne
) , so all of its fields are mapped to the same DB table and there is no reasons it will lead to separate database calls to load an entity.
spring-data-jpa also provides a base entity AbstractAuditable
which developer can choose to use it rather than create by their own (though using it will increase the coupling of the entity to Spring Data) , so making the base entity as a separate shared JAR and let other projects to use is very common. It is even a good practise if your company have some rules that all entities must have certain set of fields like id , createdBy etc. mainly because it can make the codes DRY as said by you.