Entity mapping and relationships
Key mapping annotations:
@Entityand@Table(name = ...)@Idwith@GeneratedValue: preferSEQUENCEon PostgreSQL, becauseIDENTITYdisables JDBC insert batching@Column(nullable = false, unique = true)and@Enumerated(EnumType.STRING)@Embeddedvalue objects, and@Versionfor optimistic locking
Relationships:
@ManyToOne: the side holding the foreign key, called the owning side.@OneToMany(mappedBy = ...): the inverse side.@OneToOneand@ManyToMany(usually better modelled as an explicit join entity).
Fetch defaults: @ManyToOne and @OneToOne are EAGER; collections are LAZY. Set fetch = LAZY on every @ManyToOne and fetch explicitly when you need the data.
Example
@Entity
@Table(name = "course")
public class Course {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
@Column(nullable = false, length = 150)
private String title;
@Enumerated(EnumType.STRING)
private Level level;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "author_id")
private Author author;
@OneToMany(mappedBy = "course", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Lesson> lessons = new ArrayList<>();
@Version
private int version;
protected Course() {} // required by JPA
public void addLesson(Lesson l) { // keep both sides in sync
lessons.add(l);
l.setCourse(this);
}
}Common mistake
Calling course.getLessons().add(lesson) without lesson.setCourse(course). The foreign key stays null. Use helper methods that set both sides.
Under the hood
Only the owning side (the @ManyToOne, the side without mappedBy) is used to write the foreign key; changing only the inverse collection does nothing in the database. Avoid CascadeType.REMOVE on @ManyToMany, which can delete shared rows. orphanRemoval = true deletes children that you remove from the collection.
Check yourself
In Course and Lesson, which side owns the foreign key?
How this connects
Know these first
Part of Job-ready backend developer.
Was this lesson helpful?
Finished reading? Mark it complete to track your progress.