The Curator-Project – Implementing the data structure

As this service ist the first of several I’ll invest a little bit more in a generic approach. Some of the generics and abstract classes might seem a little bit over the top.

I’ll as well use Lombok even it’s not the considered for some functionality on the entities. Feel free to de-lombok the functions. For now it will spare me some boilerplate.

Metadata

All of entities will implement the interface MetaData.

public interface MetaData<T extends Serializable> {
  T getId();
  Long getVersion();
  String getCreatedBy();

  ZonedDateTime getCreatedDate();
  String getLastModifiedBy();

  ZonedDateTime getLastModifiedDate();
}

To make this a little bit more convenient the abstract class AbstractEntity offers all functions so that this methods can be called via extends.

@AllArgsConstructor
@Data
@EntityListeners(AuditingEntityListener.class)
@EqualsAndHashCode(of = {"lastModifiedBy", "lastModifiedDate", "name", "id"}, callSuper = false)
@MappedSuperclass
@NoArgsConstructor
@SuperBuilder
@ToString
@Validated
public abstract class AbstractEntity<T extends Serializable> implements MetaData<T>, View<T> {

  @Id
  @GeneratedValue(strategy = GenerationType.UUID)
  @Column(name = "ID", nullable = false, unique = true)
  private T id;

  @NotBlank
  @Size(min = 3, max = 50)
  @Column(name = "NAME", length = 50)
  private String name;

  @Version
  @Column(name = "VERSION")
  private Long version;

  @CreatedBy
  @Column(name = "CREATED_BY")
  private String createdBy;

  @CreatedDate
  @Column(name = "CREATED_DATE")
  private ZonedDateTime createdDate;

  @LastModifiedBy
  @Column(name = "LAST_MODIFIED_BY")
  private String lastModifiedBy;

  @LastModifiedDate
  @Column(name = "LAST_MODIFIED_DATE")
  private ZonedDateTime lastModifiedDate;

  @Builder.Default
  @Convert(converter = MapStringConverter.class)
  @Column(name = "attributes", nullable = false)
  private Map<String, String> attributes = new HashMap<>();
}

At this point the strategy of the id-generation is generic as a type but the annotation doesn’t support this. This a known Bug for the moment.

UserEntity

All entities extend from the abstract class AbstractEntity. The UserEntity is an example how this is done.

@AllArgsConstructor
@Data
@Entity
@EqualsAndHashCode(callSuper = false)
@NoArgsConstructor
@SuperBuilder
@Table(name = "USERS")
@ToString
@Validated
public class UserEntity extends AbstractEntity<UUID> {

  @NotBlank
  @Size(min = 3, max = 50)
  @Column(name = "FIRSTNAME", length = 50)
  private String firstname;

  @NotBlank
  @Size(min = 3, max = 50)
  @Column(name = "LASTNAME", length = 50)
  private String lastname;

  @NotBlank
  @Size(min = 3, max = 50)
  @Column(name = "PASSWORD", length = 50)
  @ToString.Exclude
  private String password;

  @OneToOne(cascade = CascadeType.ALL)
  @ToString.Exclude
  @JoinColumn(name = "DOCUMENT", referencedColumnName = "id")
  private DocumentEntity document;
}

The other classes can be found in the git-repo which I’ll link in the next few weeks.