I have several JPA entities, each Entity has a database user column, in that column I have to store the user that makes changes to a specific row in the table.
I created a 'MappedSuperclass' Bean that all the entities would extend from, this is the MappedSuperclass.
@MappedSuperclass
public abstract class AuditableBean {
@Column(name = "modifier_user", nullable = false)
private String modifier_user;
// Getters and Setters
}
This is one Entity that extends from the 'MappedSuperclass'.
@Entity
@Table(name = "nm_area_ref")
public class ServingAreaReferenceBean extends AuditableBean {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "nm_area_ref_id")
private UUID id;
@Column(name = "nm_srv_area_desc", nullable = false)
private String description;
@Column(name = "nm_retired", nullable = false)
private boolean retired;
// Getters and Setters
}
And, all the Beans has a corresponding service method used to save the data on the database, this is one of the services class (each service injects a repository for CRUD operations).
// Service
@Component
public class ServingAreaReferenceBO {
@Inject private ServingAreaReferenceRepository repository; //repository injection
@Inject private CloudContextProvider cloudContextProvider;
public List<ServingAreaReferenceBean> getAllServingAreaReferences() {
return Lists.newArrayList(repository.findAll());
}
public Optional<ServingAreaReferenceBean> findById(UUID id) {
return repository.findById(id);
}
public ServingAreaReferenceBean create(ServingAreaReferenceBean servingAreaReference) {
Optional<CloudContext> cloudContext = Optional.ofNullable(cloudContextProvider.get());// line 1
servingAreaReference.setUpdaterUser(cloudContext.map(CloudContext::getUserId).orElse(null));// line 2
return repository.save(servingAreaReference);// line 3
}
}
// Repository - It extends from CrudRepository (insert, update, delete operations)
@Repository
public interface ServingAreaReferenceRepository extends CrudRepository<ServingAreaReferenceBean, UUID> {
boolean existsByDescription(String description);
boolean existsByDescriptionAndIdIsNot(String description, UUID id);
}
When 'repository.save()' (line 3) executes, It stores the user successfully, but I put the user logic just before executing the save method (lines 1, 2). So I don't think that repeating those two lines on each service would be the best approach, instead, I'd like to implement a generic method or a generic class that sets the user for all the Bean Entities before executing the save method.
Is that possible? what is the better approach for that?
I was thinking to implement something like this, but not sure how to make it generic?
@Component
public class AuditableBeanHandler {
@Inject private CloudContextProvider cloudContextProvider;
public AuditableBean populateAuditInformation(AuditableBean auditableBean) {
Optional<CloudContext> cloudContext = Optional.ofNullable(CloudContextProvider.get());
auditableBean.setUpdaterUser(CloudContext.map(cloudContext::getUserId).orElse(null));
return auditableBean;
}
}