package com.tutego.ch_06.read;
import com.tutego.ch_06.advanced.Photo;
import com.tutego.ch_06.advanced.Unicorn;
import jakarta.persistence.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
@Entity // entity bean class
@Table(name = "PROFILE") // case isn't relevant
@Access(AccessType.FIELD) // Jakarta Persistence provider is informed that the data is stored within the object’s variables instead of being accessed through setter/getter methods
@NamedQueries(
value = {
@NamedQuery(
name = "Profile.findAll",
query = "SELECT p FROM Profile AS p"
),
@NamedQuery(
name = "Profile.findByNickname",
query = "SELECT p FROM Profile AS p WHERE p.nickname = :nickname"
)
}
)
@NamedNativeQueries( // uses SQL, not JPQL
value = {
@NamedNativeQuery(
name = "Profile.findFuzzyNickname",
query = "SELECT * FROM Profile WHERE SOUNDEX(nickname) = SOUNDEX(?)",
resultClass = Profile.class
),
@NamedNativeQuery(
name = "Profile.containsTwoVowelsNickname",
query = "SELECT nickname, manelength FROM profile WHERE REGEXP_LIKE(nickname, '[aeiou]{2}', 'i')",
resultSetMapping = "tupleToShortProfile"
)
}
)
@SqlResultSetMappings(
value = {
@SqlResultSetMapping(
name = "tupleToShortProfile",
classes = {
@ConstructorResult(
targetClass = ShortProfile.class,
columns = {
// name element references the name of a column in the SELECT list
@ColumnResult(name = "nickname"),
@ColumnResult(name = "manelength")
}
)
}
)
}
)
public class Profile {
@Id
// GenerationType.UUID uses v4, a custom generator is required for v7
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String nickname;
private LocalDate birthdate;
@Column(name = "manelength")
private short maneLength;
@Convert(converter = GenderConverter.class)
private Gender gender;
@Column(name = "attracted_to_gender")
private Byte attractedToGender;
private String description;
@Column(name = "lastseen")
private LocalDateTime lastSeen;
@Transient
private int meaningOfLife;
// bi-directional mapping
@OneToOne(mappedBy = "profile" /* Unicorn.profile */)
private Unicorn unicorn;
@OrderBy("created")
@OneToMany(mappedBy = "profile", fetch = FetchType.EAGER)
private List<Photo> photos;
public void setManeLength(short maneLength) {
this.maneLength = maneLength;
}
public short getManeLength() {
return maneLength;
}
public String getNickname() {
return nickname;
}
public Long getId() {
return id;
}
public LocalDate getBirthdate() {
return birthdate;
}
public List<Photo> getPhotos() {
return photos;
}
@Override
public boolean equals(Object o) {
return o instanceof Profile profile && Objects.equals(nickname, profile.nickname);
}
@Override
public int hashCode() {
return Objects.hashCode(nickname);
}
@Override
public String toString() {
return "%s[id=%d]".formatted(getClass().getSimpleName(), id);
}
}