feat(model): add PersonNameAlias entity, type enum, repository, DTO
Introduces the alias domain model: entity with @ManyToOne to Person, @OneToMany on Person for JPA graph navigation, repository with sort_order queries, input DTO, and ALIAS_NOT_FOUND error code. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,9 @@
|
|||||||
|
package org.raddatz.familienarchiv.dto;
|
||||||
|
|
||||||
|
import org.raddatz.familienarchiv.model.PersonNameAliasType;
|
||||||
|
|
||||||
|
public record PersonNameAliasDTO(
|
||||||
|
String lastName,
|
||||||
|
String firstName,
|
||||||
|
PersonNameAliasType type
|
||||||
|
) {}
|
||||||
@@ -11,6 +11,8 @@ public enum ErrorCode {
|
|||||||
// --- Persons ---
|
// --- Persons ---
|
||||||
/** A person with the given ID does not exist. 404 */
|
/** A person with the given ID does not exist. 404 */
|
||||||
PERSON_NOT_FOUND,
|
PERSON_NOT_FOUND,
|
||||||
|
/** A person name alias with the given ID does not exist. 404 */
|
||||||
|
ALIAS_NOT_FOUND,
|
||||||
|
|
||||||
// --- Documents ---
|
// --- Documents ---
|
||||||
/** A document with the given ID does not exist. 404 */
|
/** A document with the given ID does not exist. 404 */
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
package org.raddatz.familienarchiv.model;
|
package org.raddatz.familienarchiv.model;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "persons")
|
@Table(name = "persons")
|
||||||
@@ -35,4 +38,12 @@ public class Person {
|
|||||||
|
|
||||||
private Integer birthYear;
|
private Integer birthYear;
|
||||||
private Integer deathYear;
|
private Integer deathYear;
|
||||||
|
|
||||||
|
// Entity-graph navigation for JPA JOIN queries (e.g. DocumentSpecifications.hasText).
|
||||||
|
// Uses entity relationship rather than cross-domain repository access, avoiding a
|
||||||
|
// separate DB roundtrip while respecting domain boundaries.
|
||||||
|
@OneToMany(mappedBy = "person", cascade = CascadeType.ALL, orphanRemoval = true)
|
||||||
|
@JsonIgnore
|
||||||
|
@Builder.Default
|
||||||
|
private List<PersonNameAlias> nameAliases = new ArrayList<>();
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package org.raddatz.familienarchiv.model;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.*;
|
||||||
|
import org.hibernate.annotations.CreationTimestamp;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "person_name_aliases")
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public class PersonNameAlias {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.UUID)
|
||||||
|
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private UUID id;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
@JoinColumn(name = "person_id", nullable = false)
|
||||||
|
private Person person;
|
||||||
|
|
||||||
|
@Column(name = "last_name", nullable = false)
|
||||||
|
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private String lastName;
|
||||||
|
|
||||||
|
@Column(name = "first_name")
|
||||||
|
private String firstName;
|
||||||
|
|
||||||
|
@Enumerated(EnumType.STRING)
|
||||||
|
@Column(nullable = false)
|
||||||
|
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private PersonNameAliasType type;
|
||||||
|
|
||||||
|
@Column(name = "sort_order", nullable = false)
|
||||||
|
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private Integer sortOrder;
|
||||||
|
|
||||||
|
@CreationTimestamp
|
||||||
|
@Column(name = "created_at", updatable = false)
|
||||||
|
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private Instant createdAt;
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package org.raddatz.familienarchiv.model;
|
||||||
|
|
||||||
|
public enum PersonNameAliasType {
|
||||||
|
BIRTH,
|
||||||
|
WIDOWED,
|
||||||
|
DIVORCED,
|
||||||
|
OTHER
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package org.raddatz.familienarchiv.repository;
|
||||||
|
|
||||||
|
import org.raddatz.familienarchiv.model.PersonNameAlias;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.Query;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public interface PersonNameAliasRepository extends JpaRepository<PersonNameAlias, UUID> {
|
||||||
|
|
||||||
|
List<PersonNameAlias> findByPersonIdOrderBySortOrderAscCreatedAtAsc(UUID personId);
|
||||||
|
|
||||||
|
@Query("SELECT COALESCE(MAX(a.sortOrder), -1) FROM PersonNameAlias a WHERE a.person.id = :personId")
|
||||||
|
int findMaxSortOrder(UUID personId);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user