diff --git a/core/src/main/java/se/su/dsv/scipro/grading/ApprovedEvent.java b/core/src/main/java/se/su/dsv/scipro/grading/ApprovedEvent.java
index dfe7e5b08b..88160eb8a9 100644
--- a/core/src/main/java/se/su/dsv/scipro/grading/ApprovedEvent.java
+++ b/core/src/main/java/se/su/dsv/scipro/grading/ApprovedEvent.java
@@ -16,20 +16,31 @@ import java.time.Instant;
 import java.util.Objects;
 
 @Entity
-@Table(name = "grading_history_approvals")
+@Table(name = "grading_history_approval")
 public class ApprovedEvent {
+
+    // ----------------------------------------------------------------------------------
+    // Basic JPA-mappings
+    // ----------------------------------------------------------------------------------
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private Long id;
 
-    @ManyToOne
-    @JoinColumn(name = "project_id")
-    private Project project;
-
     @Temporal(TemporalType.TIMESTAMP)
     @Column(name = "`when`")
     private Instant when;
 
+    // ----------------------------------------------------------------------------------
+    // JPA-mappings of foreign keys in this table (grading_history_rejections) referencing
+    // other tables.
+    // ----------------------------------------------------------------------------------
+    @ManyToOne
+    @JoinColumn(name = "project_id")
+    private Project project;
+
+    // ----------------------------------------------------------------------------------
+    // Properties (Getters and Setters)
+    // ----------------------------------------------------------------------------------
     public Long getId() {
         return id;
     }
@@ -38,14 +49,6 @@ public class ApprovedEvent {
         this.id = id;
     }
 
-    public Project getProject() {
-        return project;
-    }
-
-    public void setProject(Project project) {
-        this.project = project;
-    }
-
     public Instant getWhen() {
         return when;
     }
@@ -54,6 +57,17 @@ public class ApprovedEvent {
         this.when = when;
     }
 
+    public Project getProject() {
+        return project;
+    }
+
+    public void setProject(Project project) {
+        this.project = project;
+    }
+
+    // ----------------------------------------------------------------------------------
+    // Methods Common To All Objects
+    // ----------------------------------------------------------------------------------
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
@@ -70,10 +84,7 @@ public class ApprovedEvent {
 
     @Override
     public String toString() {
-        return "ApprovedEvent{" +
-                "id=" + id +
-                ", project=" + project +
-                ", when=" + when +
-                '}';
+        return "ApprovedEvent{" + "id=" + id + ", project=" + project +
+                ", when=" + when + '}';
     }
 }
diff --git a/core/src/main/java/se/su/dsv/scipro/grading/NationalSubjectCategory.java b/core/src/main/java/se/su/dsv/scipro/grading/NationalSubjectCategory.java
index 26323389d8..1aa51eca5c 100644
--- a/core/src/main/java/se/su/dsv/scipro/grading/NationalSubjectCategory.java
+++ b/core/src/main/java/se/su/dsv/scipro/grading/NationalSubjectCategory.java
@@ -12,15 +12,14 @@ import java.util.Objects;
 @Entity
 @Table(name = "national_subject_category")
 public class NationalSubjectCategory {
+    // ----------------------------------------------------------------------------------
+    // Basic JPA-mappings
+    // ----------------------------------------------------------------------------------
     @Id
     @GeneratedValue(strategy = jakarta.persistence.GenerationType.IDENTITY)
     @Column(name = "id")
     private Long id;
 
-    @Basic
-    @Column(name = "external_id")
-    private Integer externalId;
-
     @Basic
     @Column(name = "swedish_name")
     private String swedishName;
@@ -37,9 +36,19 @@ public class NationalSubjectCategory {
     @Column(name = "preselected")
     private boolean preselected;
 
+    @Basic
+    @Column(name = "external_id")
+    private Integer externalId;
+
+    // ----------------------------------------------------------------------------------
+    // Constructor
+    // ----------------------------------------------------------------------------------
     public NationalSubjectCategory() {
     }
 
+    // ----------------------------------------------------------------------------------
+    // Properties (Getters and Setters)
+    // ----------------------------------------------------------------------------------
     public Long getId() {
         return id;
     }
@@ -48,14 +57,6 @@ public class NationalSubjectCategory {
         this.id = id;
     }
 
-    public Integer getExternalId() {
-        return externalId;
-    }
-
-    public void setExternalId(Integer externalId) {
-        this.externalId = externalId;
-    }
-
     public String getSwedishName() {
         return swedishName;
     }
@@ -88,6 +89,17 @@ public class NationalSubjectCategory {
         this.preselected = preselected;
     }
 
+    public Integer getExternalId() {
+        return externalId;
+    }
+
+    public void setExternalId(Integer externalId) {
+        this.externalId = externalId;
+    }
+
+    // ----------------------------------------------------------------------------------
+    // Methods Common To All Objects
+    // ----------------------------------------------------------------------------------
     @Override
     public boolean equals(Object o) {
         if (this == o) {
diff --git a/core/src/main/java/se/su/dsv/scipro/grading/PublicationMetadata.java b/core/src/main/java/se/su/dsv/scipro/grading/PublicationMetadata.java
index 87b0a82f6c..1a5028425d 100644
--- a/core/src/main/java/se/su/dsv/scipro/grading/PublicationMetadata.java
+++ b/core/src/main/java/se/su/dsv/scipro/grading/PublicationMetadata.java
@@ -17,14 +17,13 @@ import java.util.Objects;
 @Entity
 @Table(name = "publication_metadata")
 public class PublicationMetadata {
-
+    // ----------------------------------------------------------------------------------
+    // Basic JPA-mappings
+    // ----------------------------------------------------------------------------------
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private Long id;
 
-    @OneToOne(optional = false)
-    private Project project;
-
     @Basic
     @Column(name = "abstract_swedish")
     private String abstractSwedish;
@@ -41,10 +40,21 @@ public class PublicationMetadata {
     @Column(name = "keywords_english")
     private String keywordsEnglish;
 
+    // ----------------------------------------------------------------------------------
+    // JPA-mappings of foreign keys in this table (publication_metadata) referencing
+    // other tables.
+    // ----------------------------------------------------------------------------------
     @ManyToOne
     @JoinColumn(name = "national_subject_category_id")
     private NationalSubjectCategory nationalSubjectCategory;;
 
+    @OneToOne(optional = false)
+    @JoinColumn(name = "project_id")
+    private Project project;
+
+    // ----------------------------------------------------------------------------------
+    // Properties (Getters and Setters)
+    // ----------------------------------------------------------------------------------
     public Long getId() {
         return id;
     }
@@ -53,14 +63,6 @@ public class PublicationMetadata {
         this.id = id;
     }
 
-    public Project getProject() {
-        return project;
-    }
-
-    public void setProject(Project project) {
-        this.project = project;
-    }
-
     public String getAbstractSwedish() {
         return abstractSwedish;
     }
@@ -101,19 +103,17 @@ public class PublicationMetadata {
         this.nationalSubjectCategory = nationalSubjectCategory;
     }
 
-    @Override
-    public String toString() {
-        return "PublicationMetadata{" +
-                "id=" + id +
-                ", project=" + project +
-                ", abstractSwedish='" + abstractSwedish + '\'' +
-                ", abstractEnglish='" + abstractEnglish + '\'' +
-                ", keywordsSwedish='" + keywordsSwedish + '\'' +
-                ", keywordsEnglish='" + keywordsEnglish + '\'' +
-                ", nationalSubjectCategory=" + nationalSubjectCategory + '\'' +
-                '}';
+    public Project getProject() {
+        return project;
     }
 
+    public void setProject(Project project) {
+        this.project = project;
+    }
+
+    // ----------------------------------------------------------------------------------
+    // Methods Common To All Objects
+    // ----------------------------------------------------------------------------------
     @Override
     public boolean equals(Object o) {
         return o instanceof PublicationMetadata that &&
@@ -124,4 +124,15 @@ public class PublicationMetadata {
     public int hashCode() {
         return Objects.hashCode(id);
     }
+
+    @Override
+    public String toString() {
+        return "PublicationMetadata{" + "id=" + id + ", project=" + project +
+                ", abstractSwedish='" + abstractSwedish + '\'' +
+                ", abstractEnglish='" + abstractEnglish + '\'' +
+                ", keywordsSwedish='" + keywordsSwedish + '\'' +
+                ", keywordsEnglish='" + keywordsEnglish + '\'' +
+                ", nationalSubjectCategory=" + nationalSubjectCategory + '\'' +
+                '}';
+    }
 }
diff --git a/core/src/main/java/se/su/dsv/scipro/grading/RejectionEvent.java b/core/src/main/java/se/su/dsv/scipro/grading/RejectionEvent.java
index 745eaf14a8..d7a24907e3 100644
--- a/core/src/main/java/se/su/dsv/scipro/grading/RejectionEvent.java
+++ b/core/src/main/java/se/su/dsv/scipro/grading/RejectionEvent.java
@@ -17,23 +17,35 @@ import java.time.Instant;
 import java.util.Objects;
 
 @Entity
-@Table(name = "grading_history_rejections")
+@Table(name = "grading_history_rejection")
 public class RejectionEvent {
+
+    // ----------------------------------------------------------------------------------
+    // Basic JPA-mappings
+    // ----------------------------------------------------------------------------------
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private Long id;
 
-    @ManyToOne
-    @JoinColumn(name = "project_id")
-    private Project project;
+    @Basic
+    @Column(name = "reason")
+    private String reason;
 
     @Temporal(TemporalType.TIMESTAMP)
     @Column(name = "`when`")
     private Instant when;
 
-    @Basic
-    private String reason;
+    // ----------------------------------------------------------------------------------
+    // JPA-mappings of foreign keys in this table (grading_history_rejections) referencing
+    // other tables.
+    // ----------------------------------------------------------------------------------
+    @ManyToOne
+    @JoinColumn(name = "project_id")
+    private Project project;
 
+    // ----------------------------------------------------------------------------------
+    // Properties (Getters and Setters)
+    // ----------------------------------------------------------------------------------
     public Long getId() {
         return id;
     }
@@ -42,22 +54,6 @@ public class RejectionEvent {
         this.id = id;
     }
 
-    public Project getProject() {
-        return project;
-    }
-
-    public void setProject(Project project) {
-        this.project = project;
-    }
-
-    public Instant getWhen() {
-        return when;
-    }
-
-    public void setWhen(Instant when) {
-        this.when = when;
-    }
-
     public String getReason() {
         return reason;
     }
@@ -66,6 +62,25 @@ public class RejectionEvent {
         this.reason = reason;
     }
 
+    public Instant getWhen() {
+        return when;
+    }
+
+    public void setWhen(Instant when) {
+        this.when = when;
+    }
+
+    public Project getProject() {
+        return project;
+    }
+
+    public void setProject(Project project) {
+        this.project = project;
+    }
+
+    // ----------------------------------------------------------------------------------
+    // Methods Common To All Objects
+    // ----------------------------------------------------------------------------------
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
diff --git a/core/src/main/java/se/su/dsv/scipro/project/Project.java b/core/src/main/java/se/su/dsv/scipro/project/Project.java
index ef9404b880..1f338b20d1 100755
--- a/core/src/main/java/se/su/dsv/scipro/project/Project.java
+++ b/core/src/main/java/se/su/dsv/scipro/project/Project.java
@@ -56,18 +56,30 @@ public class Project extends DomainObject {
     public static final String NO_CO_SUPERVISOR = "No co-supervisor";
     public static final int TITLE_MAX_LENGTH = 255;
 
+    public static ITitle builder() {
+        return new Builder();
+    }
+
+    // ----------------------------------------------------------------------------------
+    // Basic JPA-mappings
+    // ----------------------------------------------------------------------------------
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private Long id;
 
-    @Basic
-    @Column(unique = true)
-    private Integer identifier;
-
     @Basic(optional = false)
-    @Column(length = TITLE_MAX_LENGTH)
+    @Column(name = "title", length = TITLE_MAX_LENGTH)
     private String title;
 
+    @Basic
+    @Column(name = "credits")
+    private int credits;
+
+    @Basic
+    @Column(name = "language")
+    @Enumerated(EnumType.STRING)
+    private Language language;
+
     @Basic(optional = false)
     @Column(name = "start_date", nullable = false)
     private LocalDate startDate;
@@ -76,63 +88,91 @@ public class Project extends DomainObject {
     @Column(name = "expected_end_date")
     private LocalDate expectedEndDate;
 
-    @ManyToMany
-    @JoinTable(name = "project_user", inverseJoinColumns = @JoinColumn(name = "user_id"))
-    private Set<User> projectParticipants = new TreeSet<>(new User.ByNameComparator());
-
-    @ManyToMany
-    @JoinTable(name = "project_reviewer", inverseJoinColumns = @JoinColumn(name = "user_id"))
-    private Set<User> reviewers = new TreeSet<>(new User.ByNameComparator());
-
-    @ManyToMany
-    @JoinTable(name = "project_cosupervisor", inverseJoinColumns = @JoinColumn(name = "user_id"))
-    private Set<User> coSupervisors = new TreeSet<>(new User.ByNameComparator());
-
-    @ManyToOne(optional = false)
-    @QueryInit({"unit"})
-    @JoinColumn(name = "supervisor_id", referencedColumnName = "id")
-    private User headSupervisor;
-
+    @Basic
+    @Column(name = "project_status")
     @Enumerated(EnumType.STRING)
     private ProjectStatus projectStatus = ProjectStatus.ACTIVE;
 
+    @Basic
+    @Column(name = "final_seminar_rule_exmpt")
+    private boolean finalSeminarRuleExempted = false;
+
+    @Basic
+    @Column(name = "state_of_mind")
     @Enumerated(EnumType.STRING)
     private StateOfMind stateOfMind = StateOfMind.FINE;
 
     @Basic(optional = true)
-    private Date stateOfMindDate;
-
-    @Basic(optional = true)
+    @Column(name = "state_of_mind_reason")
     private String stateOfMindReason;
 
+    @Basic(optional = true)
+    @Column(name = "state_of_mind_date")
+    private Date stateOfMindDate;
+
+    @Basic
+    @Column(name = "daisy_identifier", unique = true)
+    private Integer identifier;
+
+    // ----------------------------------------------------------------------------------
+    // Embedded JPA-mappings
+    // ----------------------------------------------------------------------------------
+    @Embedded
+    @AttributeOverride(name = "name", column = @Column(name = "external_organization"))
+    private ExternalOrganization externalOrganization;
+
+    // ----------------------------------------------------------------------------------
+    // JPA-mappings of foreign keys in this table (opposition_report) referencing other
+    // tables.
+    // ----------------------------------------------------------------------------------
     @ManyToOne(optional = false)
     @JoinColumn(name = "project_type_id", referencedColumnName = "id")
     private ProjectType projectType;
 
-    @Embedded
-    @AttributeOverride(name = "name", column = @Column(name = "externalOrganization"))
-    private ExternalOrganization externalOrganization;
-
-    @Column(name = "fs_rule_exmpt")
-    private boolean finalSeminarRuleExempted = false;
-
-    @Basic
-    private int credits;
-
     @ManyToOne(optional = true)
     @JoinColumn(name = "research_area_id", referencedColumnName = "id")
     private ResearchArea researchArea;
 
-    @Enumerated(EnumType.STRING)
-    private Language language;
+    @ManyToOne(optional = false)
+    @JoinColumn(name = "supervisor_id", referencedColumnName = "id")
+    @QueryInit({"unit"})
+    private User headSupervisor;
 
+    // ----------------------------------------------------------------------------------
+    // @ManyToMany JPA-mappings
+    // ----------------------------------------------------------------------------------
+    @ManyToMany
+    @JoinTable(name = "project_user",
+            joinColumns = @JoinColumn(name = "project_id", referencedColumnName = "id"),
+            inverseJoinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"))
+    private Set<User> projectParticipants = new TreeSet<>(new User.ByNameComparator());
+
+    @ManyToMany
+    @JoinTable(name = "project_reviewer",
+            joinColumns = @JoinColumn(name = "project_id", referencedColumnName = "id"),
+            inverseJoinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"))
+    private Set<User> reviewers = new TreeSet<>(new User.ByNameComparator());
+
+    @ManyToMany
+    @JoinTable(name = "project_cosupervisor",
+            joinColumns = @JoinColumn(name = "project_id", referencedColumnName = "id"),
+            inverseJoinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"))
+    private Set<User> coSupervisors = new TreeSet<>(new User.ByNameComparator());
+
+    // ----------------------------------------------------------------------------------
+    // JPA-mappings of other tables referencing to this table "project"
+    // ----------------------------------------------------------------------------------
     @ElementCollection(fetch = FetchType.LAZY)
-    @CollectionTable(name = "project_user_note", joinColumns = @JoinColumn(name = "project_id"))
+    @CollectionTable(name = "project_user_note",
+            joinColumns = @JoinColumn(name = "project_id", referencedColumnName = "id"))
     @Column(name = "note")
     @SuppressWarnings("JpaDataSourceORMInspection")  // false warning from IntelliJ for the @MapKeyJoinColumn
     @MapKeyJoinColumn(name = "user_id")
     private Map<User, String> userNotes = new HashMap<>();
 
+    // ----------------------------------------------------------------------------------
+    // JPA Lifecycle Methods
+    // ----------------------------------------------------------------------------------
     @PrePersist
     @PreUpdate
     void cleanTitle() {
@@ -142,12 +182,68 @@ public class Project extends DomainObject {
         title = title.trim();
     }
 
-    public Map<User, String> getUserNotes() {
-        return userNotes;
+    // ----------------------------------------------------------------------------------
+    // Properties (Getters and Setters)
+    // ----------------------------------------------------------------------------------
+
+    @Override
+    public Long getId() {
+        return this.id;
     }
 
-    public void setUserNotes(Map<User, String> userNotes) {
-        this.userNotes = userNotes;
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getTitle() {
+        return SciProUtilities.cleanString(title);
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public int getCredits() {
+        return this.credits;
+    }
+
+    public void setCredits(int credits) {
+        this.credits = credits;
+    }
+
+    public Language getLanguage() {
+        return this.language;
+    }
+
+    public void setLanguage(Language language) {
+        this.language = language;
+    }
+
+    public LocalDate getStartDate() {
+        return startDate;
+    }
+
+    public void setStartDate(LocalDate startDate) {
+        this.startDate = startDate;
+    }
+
+    public LocalDate getExpectedEndDate() {
+        return this.expectedEndDate;
+    }
+
+    public void setExpectedEndDate(LocalDate expectedEndDate) {
+        this.expectedEndDate = expectedEndDate;
+    }
+
+    public ProjectStatus getProjectStatus() {
+        return this.projectStatus;
+    }
+
+    public void setProjectStatus(ProjectStatus projectStatus) {
+        this.projectStatus = projectStatus;
+        if (projectStatus == ProjectStatus.COMPLETED) {
+            this.stateOfMind = StateOfMind.FINE;
+        }
     }
 
     public boolean isFinalSeminarRuleExempted() {
@@ -158,53 +254,20 @@ public class Project extends DomainObject {
         this.finalSeminarRuleExempted = finalSeminarRuleExempted;
     }
 
-    public User getHeadSupervisor() {
-        return headSupervisor;
+    public StateOfMind getStateOfMind() {
+        return this.stateOfMind;
     }
 
-    public ProjectType getProjectType() {
-        return projectType;
+    public void setStateOfMind(StateOfMind stateOfMind) {
+        this.stateOfMind = stateOfMind;
     }
 
-    public SortedSet<User> getCoSupervisors() {
-        TreeSet<User> s = new TreeSet<>(new User.ByNameComparator());
-        s.addAll(coSupervisors);
-        return Collections.unmodifiableSortedSet(s);
+    public String getStateOfMindReason() {
+        return this.stateOfMindReason;
     }
 
-    public void setCoSupervisors(Collection<User> coSupervisors) {
-        this.coSupervisors.clear();
-        this.coSupervisors.addAll(coSupervisors);
-    }
-
-    public void addCoSupervisor(User coSupervisor) {
-        coSupervisors.add(coSupervisor);
-    }
-
-    public SortedSet<User> getReviewers() {
-        TreeSet<User> s = new TreeSet<>(new User.ByNameComparator());
-        s.addAll(reviewers);
-        return Collections.unmodifiableSortedSet(s);
-    }
-
-    public void setReviewers(Collection<User> reviewers) {
-        this.reviewers.clear();
-        this.reviewers.addAll(reviewers);
-    }
-
-    public void addReviewer(User reviewer) {
-        reviewers.add(reviewer);
-    }
-
-    public void removeReviewer(User reviewer) {
-        reviewers.remove(reviewer);
-    }
-
-    public void setProjectStatus(ProjectStatus projectStatus) {
-        this.projectStatus = projectStatus;
-        if (projectStatus == ProjectStatus.COMPLETED) {
-            this.stateOfMind = StateOfMind.FINE;
-        }
+    public void setStateOfMindReason(String stateOfMindReason) {
+        this.stateOfMindReason = stateOfMindReason;
     }
 
     public Date getStateOfMindDate() {
@@ -217,8 +280,44 @@ public class Project extends DomainObject {
                 : new Date(stateOfMindDate.getTime());
     }
 
-    public String getTitle() {
-        return SciProUtilities.cleanString(title);
+    public Integer getIdentifier() {
+        return this.identifier;
+    }
+
+    public void setIdentifier(Integer identifier) {
+        this.identifier = identifier;
+    }
+
+    public ExternalOrganization getExternalOrganization() {
+        return this.externalOrganization;
+    }
+
+    public void setExternalOrganization(ExternalOrganization externalOrganization) {
+        this.externalOrganization = externalOrganization;
+    }
+
+    public ProjectType getProjectType() {
+        return projectType;
+    }
+
+    public void setProjectType(ProjectType projectType) {
+        this.projectType = projectType;
+    }
+
+    public ResearchArea getResearchArea() {
+        return this.researchArea;
+    }
+
+    public void setResearchArea(ResearchArea researchArea) {
+        this.researchArea = researchArea;
+    }
+
+    public User getHeadSupervisor() {
+        return headSupervisor;
+    }
+
+    public void setHeadSupervisor(User headSupervisor) {
+        this.headSupervisor = headSupervisor;
     }
 
     public SortedSet<User> getProjectParticipants() {
@@ -232,11 +331,91 @@ public class Project extends DomainObject {
         this.projectParticipants.addAll(projectParticipants);
     }
 
+    public SortedSet<User> getReviewers() {
+        TreeSet<User> s = new TreeSet<>(new User.ByNameComparator());
+        s.addAll(reviewers);
+        return Collections.unmodifiableSortedSet(s);
+    }
+
+    public void setReviewers(Collection<User> reviewers) {
+        this.reviewers.clear();
+        this.reviewers.addAll(reviewers);
+    }
+
+    public SortedSet<User> getCoSupervisors() {
+        TreeSet<User> s = new TreeSet<>(new User.ByNameComparator());
+        s.addAll(coSupervisors);
+        return Collections.unmodifiableSortedSet(s);
+    }
+
+    public void setCoSupervisors(Collection<User> coSupervisors) {
+        this.coSupervisors.clear();
+        this.coSupervisors.addAll(coSupervisors);
+    }
+
+    public Map<User, String> getUserNotes() {
+        return userNotes;
+    }
+
+    public void setUserNotes(Map<User, String> userNotes) {
+        this.userNotes = userNotes;
+    }
+
+    // ----------------------------------------------------------------------------------
+    // Methods Common To All Objects
+    // ----------------------------------------------------------------------------------
+    @Override
+    public boolean equals(final Object o) {
+        if (o == this) return true;
+        if (!(o instanceof Project)) return false;
+        final Project other = (Project) o;
+        return other.canEqual(this)
+                && Objects.equals(this.getId(), other.getId());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(this.getId());
+    }
+
+    @Override
+    public String toString() {
+        return "Project(id=" + this.getId() + ", identifier=" + this.getIdentifier() +
+                ", title=" + this.getTitle() + ", projectParticipants=" + this.getProjectParticipants() +
+                ", headSupervisor=" + this.getHeadSupervisor() + ", projectType=" +
+                this.getProjectType() + ")";
+    }
+
+    // ----------------------------------------------------------------------------------
+    // Other Methods
+    // ----------------------------------------------------------------------------------
+
+    protected boolean canEqual(final Object other) {
+        return other instanceof Project;
+    }
+
     public void addProjectParticipant(User s) {
         projectParticipants.add(s);
     }
 
-    //TODO remove this method
+    public boolean isParticipant(User user) {
+        for (User s : projectParticipants) {
+            if (s.equals(user)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public void addReviewer(User reviewer) {
+        reviewers.add(reviewer);
+    }
+
+    public void removeReviewer(User reviewer) {
+        reviewers.remove(reviewer);
+    }
+
+    // TODO remove this method
     public User getReviewer() {
         if (reviewers.isEmpty()) {
             return null;
@@ -245,6 +424,14 @@ public class Project extends DomainObject {
         }
     }
 
+    public String getReviewerName() {
+        return getReviewer() != null ? getReviewer().getFullName() : NO_REVIEWER;
+    }
+
+    public void addCoSupervisor(User coSupervisor) {
+        coSupervisors.add(coSupervisor);
+    }
+
     public List<Member> getMembers() {
         List<Member> members = new ArrayList<>();
 
@@ -281,23 +468,10 @@ public class Project extends DomainObject {
         return externalOrganization != null;
     }
 
-    public boolean isParticipant(User user) {
-        for (User s : projectParticipants) {
-            if (s.equals(user)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
     public String getSupervisorName() {
         return getHeadSupervisor().getFullName();
     }
 
-    public String getReviewerName() {
-        return getReviewer() != null ? getReviewer().getFullName() : NO_REVIEWER;
-    }
-
     public DegreeType getProjectTypeDegreeType() {
         return getProjectType().getDegreeType();
     }
@@ -330,10 +504,6 @@ public class Project extends DomainObject {
         return getProjectType().hasModule(projectModule);
     }
 
-    public static ITitle builder() {
-        return new Builder();
-    }
-
     public boolean isSupervisor(User user) {
         return headSupervisor != null && headSupervisor.equals(user);
     }
@@ -360,125 +530,9 @@ public class Project extends DomainObject {
         return Objects.requireNonNullElse(language, getProjectType().getDefaultLanguage());
     }
 
-    @Override
-    public Long getId() {
-        return this.id;
-    }
-
-    public Integer getIdentifier() {
-        return this.identifier;
-    }
-
-    public LocalDate getExpectedEndDate() {
-        return this.expectedEndDate;
-    }
-
-    public ProjectStatus getProjectStatus() {
-        return this.projectStatus;
-    }
-
-    public StateOfMind getStateOfMind() {
-        return this.stateOfMind;
-    }
-
-    public String getStateOfMindReason() {
-        return this.stateOfMindReason;
-    }
-
-    public ExternalOrganization getExternalOrganization() {
-        return this.externalOrganization;
-    }
-
-    public int getCredits() {
-        return this.credits;
-    }
-
-    public ResearchArea getResearchArea() {
-        return this.researchArea;
-    }
-
-    public Language getLanguage() {
-        return this.language;
-    }
-
-    public void setId(Long id) {
-        this.id = id;
-    }
-
-    public void setIdentifier(Integer identifier) {
-        this.identifier = identifier;
-    }
-
-    public void setTitle(String title) {
-        this.title = title;
-    }
-
-    public void setExpectedEndDate(LocalDate expectedEndDate) {
-        this.expectedEndDate = expectedEndDate;
-    }
-
-    public void setHeadSupervisor(User headSupervisor) {
-        this.headSupervisor = headSupervisor;
-    }
-
-    public void setStateOfMind(StateOfMind stateOfMind) {
-        this.stateOfMind = stateOfMind;
-    }
-
-    public void setStateOfMindReason(String stateOfMindReason) {
-        this.stateOfMindReason = stateOfMindReason;
-    }
-
-    public void setProjectType(ProjectType projectType) {
-        this.projectType = projectType;
-    }
-
-    public void setExternalOrganization(ExternalOrganization externalOrganization) {
-        this.externalOrganization = externalOrganization;
-    }
-
-    public void setCredits(int credits) {
-        this.credits = credits;
-    }
-
-    public void setResearchArea(ResearchArea researchArea) {
-        this.researchArea = researchArea;
-    }
-
-    public void setLanguage(Language language) {
-        this.language = language;
-    }
-
-    public LocalDate getStartDate() {
-        return startDate;
-    }
-
-    public void setStartDate(LocalDate startDate) {
-        this.startDate = startDate;
-    }
-
-    @Override
-    public boolean equals(final Object o) {
-        if (o == this) return true;
-        if (!(o instanceof Project)) return false;
-        final Project other = (Project) o;
-        return other.canEqual(this)
-                && Objects.equals(this.getId(), other.getId());
-    }
-
-    protected boolean canEqual(final Object other) {
-        return other instanceof Project;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hashCode(this.getId());
-    }
-
-    @Override
-    public String toString() {
-        return "Project(id=" + this.getId() + ", identifier=" + this.getIdentifier() + ", title=" + this.getTitle() + ", projectParticipants=" + this.getProjectParticipants() + ", headSupervisor=" + this.getHeadSupervisor() + ", projectType=" + this.getProjectType() + ")";
-    }
+    // ----------------------------------------------------------------------------------
+    // Nested classes and interfaces
+    // ----------------------------------------------------------------------------------
 
     private static class Builder implements ITitle, IProjectType, IStartDate, IBuild {
         private final Project instance = new Project();
diff --git a/core/src/main/resources/db/migration/V389__harmonize_table_attribute_name.sql b/core/src/main/resources/db/migration/V389__harmonize_table_attribute_name.sql
index d2cbcfc6c6..b5a0ea2001 100644
--- a/core/src/main/resources/db/migration/V389__harmonize_table_attribute_name.sql
+++ b/core/src/main/resources/db/migration/V389__harmonize_table_attribute_name.sql
@@ -2376,10 +2376,96 @@ alter table `grading_criterion`
  * Step 15: project and related tables
  */
 
--- todo:
+-- table: project
+
+alter table `project` drop foreign key `project_supervisor_id`;
+alter table `project` drop key `project_supervisor_id`;
+alter table `project` drop key `identifier`;
+
+alter table `project` change `version` `version` int(4) not null default 0 after `last_modified`;
+alter table `project` change `title` `title` longtext not null after `version`;
+alter table `project` change `credits` `credits` int(11) not null default 0 after `title`;
+alter table `project` change `language` `language` varchar(255) default null after credits;
+alter table `project` change `start_date` `start_date` date not null after language;
+alter table `project` change `expected_end_date` `expected_end_date` date default null after `start_date`;
+alter table `project` change `externalOrganization` `external_organization` varchar(255) default null after `expected_end_date`;
+alter table `project` change `projectStatus` `project_status` varchar(255) default null after `external_organization`;
+alter table `project` change `fs_rule_exmpt` `final_seminar_rule_exmpt` bit(1) not null default b'0' after `project_status`;
+alter table `project` change `stateOfMind` `state_of_mind` varchar(255) default null after `final_seminar_rule_exmpt`;
+alter table `project` change `stateOfMindReason` `state_of_mind_reason` varchar(255) default null after `state_of_mind`;
+alter table `project` change `stateOfMindDate` `state_of_mind_date` datetime default null after `state_of_mind_reason`;
+alter table `project` change `identifier` `daisy_identifier` bigint(20) default null after `state_of_mind_date`;
+alter table `project` change `supervisor_id` `supervisor_id` bigint(20) not null after `research_area_id`;
+
+alter table `project` add constraint uk_project_daisy_identifier unique(daisy_identifier);
+
+alter table `project`
+    add constraint fk_project_supervisor_id
+        foreign key (supervisor_id) references user (id)
+            on delete cascade on update cascade;
+
+-- table: grading_history_rejections
+
+alter table `grading_history_rejections` drop foreign key `FK_grading_history_rejections_project`;
+
+alter table `grading_history_rejections` drop key `FK_grading_history_rejections_project`;
+
+alter table `grading_history_rejections` change `reason` `reason` text not null after `id`;
+alter table `grading_history_rejections` change `when` `when` timestamp not null default '0000-00-00 00:00:00' after `reason`;
+
+rename table `grading_history_rejections` to `grading_history_rejection`;
+
+alter table `grading_history_rejection`
+    add constraint fk_grading_history_rejections_project_id
+        foreign key (project_id) references project (id)
+            on delete cascade on update cascade;
+
+-- table: grading_history_approvals
+
+alter table `grading_history_approvals` drop foreign key `FK_grading_history_approvals_project`;
+
+alter table `grading_history_approvals` drop key `FK_grading_history_approvals_project`;
+
+alter table `grading_history_approvals` change `when` `when` timestamp not null default '0000-00-00 00:00:00' after `id`;
+
+rename table `grading_history_approvals` to `grading_history_approval`;
+
+alter table `grading_history_approval`
+    add constraint fk_grading_history_approval_project_id
+        foreign key (project_id) references project (id)
+            on delete cascade on update cascade;
+
+-- table: national_subject_category
+
+alter table `national_subject_category` drop key `U_national_subject_category_external_id`;
+
+alter table `national_subject_category` change `external_id` `external_id` int(11) not null after `preselected`;
+
+alter table `national_subject_category`
+    add constraint uk_national_subject_category_external_id unique(external_id);
+
+-- table: publication_metadata
+
+alter table `publication_metadata` drop foreign key `FK_publication_metadata_project`;
+alter table `publication_metadata` drop foreign key `FK_publication_metadata_national_subject_category`;
+
+alter table `publication_metadata` drop key `FK_publication_metadata_project`;
+alter table `publication_metadata` drop key `FK_publication_metadata_national_subject_category`;
+
+alter table `publication_metadata` change `project_id` `project_id` bigint(20) not null after `national_subject_category_id`;
+
+alter table `publication_metadata`
+    add constraint fk_publication_metadata_national_subject_category_id
+        foreign key (national_subject_category_id) references national_subject_category (id)
+            on delete cascade on update cascade;
+
+alter table `publication_metadata`
+    add constraint fk_publication_metadata_project_id
+        foreign key (project_id) references project (id)
+            on delete cascade on update cascade;
 
 /*
- * Step XX: Many-to-Many tables between project and user.
+ * Step 16: Many-to-Many tables between project and user.
  */
 
 -- table: project_user_note (new changes from develop branch)
@@ -2398,6 +2484,21 @@ alter table `project_user_note`
         foreign key (user_id) references user (id)
             on delete cascade on update cascade;
 
+-- todo: table: project_cosupervisor
+
+
+-- todo: table: project_reviewer
+
+-- todo: table: project_user
+
+-- todo: table: grading_history_submissions
+
+-- todo: table: externallink
+
+-- todo: table: grade
+
+
+
 /* Useful SQL
 
 >>> SQL query for FK-to: