Module - Generated Value - Sequence Generator - Mapping
package com.example.demo.module;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
@Entity
@Table(name = "Profile")
@Getter
@Setter
public class Profile {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToOne
@JoinColumn(name = "users_id") // foreign key
private Users applicant;
private String name;
private String email;
private String phone;
private String skills;
private String education;
private String experience;
private String resumeFileAddress;
}
Summary of the Profile Entity
The
Profileclass is a JPA entity representing aProfiletable in the database.Uses Jakarta Persistence annotations for ORM mapping.
Fields:
id– Primary key, auto-generated using identity strategy.applicant– A one-to-one relationship with theUsersentity, mapped viausers_idforeign key.Other fields store profile information:
name,email,phone,skills,education,experience,resumeFileAddress.
Uses Lombok
@Getterand@Setterfor automatic getter and setter generation.
Primary Key Generation
JPA specification supports 4 different types of primary key generation strategies
GenerationType.AUTO
GenerationType.IDENTITY
GenerationType.SEQUENCE
GenerationType.Table
1. GenerationType.AUTO
Hibernate chooses the best strategy based on your database.
It might pick
SEQUENCE,IDENTITY, orTABLEdepending on DB support.
Example:
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
}
Notes:
Simple to use, good for cross-DB portability.
Hibernate decides which strategy works best.
2. GenerationType.IDENTITY
Uses database auto-increment / identity columns.
Common in MySQL, SQL Server.
Example:
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
Notes:
DB automatically generates ID during insert.
Hibernate cannot batch inserts efficiently because it needs the ID immediately after insert.
No sequence or extra table is used.
2. What happens on insert
- You create a new entity in Java:
User u = new User();
u.setName("Alice");
entityManager.persist(u);
- Hibernate executes an INSERT statement without the ID:
INSERT INTO user (name) VALUES ('Alice');
The database automatically assigns the next auto-increment ID (e.g., 1).
Hibernate retrieves the generated ID from the database using JDBC API:
In MySQL:
getGeneratedKeys()In PostgreSQL:
RETURNING id
- Hibernate then sets the ID on the entity:
u.getId(); // 1
3. GenerationType.SEQUENCE
Uses a database sequence object (if DB supports it).
Hibernate prefetches IDs using
allocationSize.
Example:
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_seq")
@SequenceGenerator(name = "user_seq", sequenceName = "user_sequence", allocationSize = 5)
private Long id;
private String name;
}
Notes:
Efficient, supports batch inserts.
DB sequence internally tracks the next value.
Safe for multiple app instances.
No explicit table is created.
First time an ID is needed:
Hibernate asks the database sequence for the next value.
DB sequence returns
1.Hibernate internally reserves IDs 1 to 5 in memory.
Next inserts:
- Hibernate just uses IDs 2, 3, 4, 5 from memory—no DB call needed.
After using up 1–5, Hibernate asks the DB sequence again:
DB sequence increments (next value = 6)
Hibernate reserves 6–10
4. GenerationType.TABLE
Uses a Hibernate-managed table to simulate sequences.
Useful for DBs without native sequences.
Example:
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "user_tab")
@TableGenerator(
name = "user_tab",
table = "hibernate_sequences",
pkColumnName = "sequence_name",
valueColumnName = "next_val",
allocationSize = 5
)
private Long id;
private String name;
}
Notes:
Hibernate reads/updates the table to generate IDs.
Works on any database.
Slightly slower than
SEQUENCEdue to extra SELECT + UPDATE.
5. Summary Table
| Strategy | How it works | DB Object Needed? | Performance | Multiple App Instances Safe? | Extra Table? |
| AUTO | Hibernate picks best | Depends | Good | ✅ Yes | Maybe |
| IDENTITY | DB auto-increment column | Yes | Moderate | ✅ Yes | ❌ No |
| SEQUENCE | DB sequence object | Yes | Fast, efficient | ✅ Yes | ❌ No |
| TABLE | Hibernate table tracks ID | No | Slower | ✅ Yes | ✅ Yes |
Key Takeaways
Use
SEQUENCEif your DB supports it → fastest, safe for multiple app instances.Use
IDENTITYfor auto-increment DBs → simple, but not batch-friendly.Use
TABLEonly if DB has no sequence support.AUTOis convenient for cross-DB portability.
1. One-to-One Mapping
Scenario: A User has one Profile.
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
private Profile profile;
// getters and setters
}
@Entity
public class Profile {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String email;
@OneToOne
@JoinColumn(name = "user_id") // foreign key in Profile table
private User user;
// getters and setters
}
Explanation:
Profilehas a foreign key toUser.mappedBy = "user"tells Hibernate thatUseris the inverse side.cascade = CascadeType.ALLensures savingUseralso savesProfile.Profileowns the relationship (@JoinColumn→ foreign key).Useris the inverse side (mappedBy = "user").You can now navigate in both directions:
Repository Example:
public interface UserRepository extends JpaRepository<User, Long> {}
public interface ProfileRepository extends JpaRepository<Profile, Long> {}
Usage:
User user = new User();
user.setName("Alice");
Profile profile = new Profile();
profile.setEmail("alice@example.com");
profile.setUser(user);
user.setProfile(profile);
userRepository.save(user); // Saves both user and profile
2. One-to-Many Mapping
Scenario: A User can have multiple Posts.
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
private List<Post> posts = new ArrayList<>();
// getters and setters
}
@Entity
public class Post {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
@ManyToOne
@JoinColumn(name = "user_id") // foreign key in Post table
private User user;
// getters and setters
}
Explanation:
Posttable has a foreign keyuser_idreferring toUser.mappedBy = "user"indicates theUserentity owns the relationship.cascade = CascadeType.ALLensures saving aUsersaves all theirPosts.Postowns the foreign key (user_id).Useris the inverse side (mappedBy = "user").Now you can navigate both ways:
Usage Example:
User user = new User();
user.setName("Bob");
Post post1 = new Post();
post1.setTitle("First Post");
post1.setUser(user);
Post post2 = new Post();
post2.setTitle("Second Post");
post2.setUser(user);
user.getPosts().add(post1);
user.getPosts().add(post2);
userRepository.save(user); // Saves user and both posts
✅ Key Points
| Mapping | Foreign Key Location | Cascade Option Example | Example Scenario |
@OneToOne | Profile table | ALL | User → Profile |
@OneToMany | Post table | ALL | User → multiple Posts |
What mappedBy means
mappedBytells Hibernate:
“This side is the inverse side of the relationship; the other side owns the foreign key.”Only the owner side manages the database foreign key.
The inverse side just maps to the owner for navigation purposes.
4. Key Points
| Side | Role | Foreign Key Managed? | mappedBy needed? |
| Owner | Manages DB relationship | Yes | ❌ No |
| Inverse (mappedBy) | Just navigates relationship | No | ✅ Yes |
Without
mappedBy, Hibernate will create an extra join table to manage the relationship.Using
mappedByavoids extra tables and makes it trulybidirectional.
1. Unidirectional One-to-One
Scenario: A User has one Profile, but Profile does not have a reference back to User.
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "profile_id") // FK in User table
private Profile profile;
// getters and setters
}
@Entity
public class Profile {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String email;
// No reference to User → unidirectional
// getters and setters
}
Explanation:
Userhas aprofile_idcolumn → foreign key.Profiledoes not know aboutUser.Navigation: User → Profile, but not Profile → User.
Usage Example:
Profile profile = new Profile();
profile.setEmail("alice@example.com");
User user = new User();
user.setName("Alice");
user.setProfile(profile);
userRepository.save(user); // Saves both User and Profile
2. Unidirectional Many-to-One
Scenario: Many Posts belong to one User, but User does not have a collection of posts.
@Entity
public class Post {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
@ManyToOne
@JoinColumn(name = "user_id") // FK in Post table
private User user;
// getters and setters
}
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
// No collection of posts → unidirectional
// getters and setters
}
Explanation:
Posttable has auser_idcolumn → foreign key.Userdoes not have aList<Post>collection.Navigation: Post → User, but not User → Posts.
Usage Example:
User user = new User();
user.setName("Bob");
userRepository.save(user);
Post post1 = new Post();
post1.setTitle("Post 1");
post1.setUser(user);
Post post2 = new Post();
post2.setTitle("Post 2");
post2.setUser(user);
postRepository.save(post1);
postRepository.save(post2);
✅ Key Points
| Mapping Type | FK Location | Navigation Available | Extra Table? | Example Scenario |
| One-to-One (uni) | User table (profile_id) | User → Profile | ❌ No | User has Profile |
| Many-to-One (uni) | Post table (user_id) | Post → User | ❌ No | Many posts belong to User |
So in short:
mappedBy= bidirectional, inverse side, does not own FKNo
mappedBy= unidirectional, or Hibernate creates extra table
Why Extra Table ? if not mapped / not referenced ?
Post has a foreign key column (user_id).
User has a OneToMany without mappedBy.
Scenario:
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany // No mappedBy
private List<Post> posts = new ArrayList<>();
}
@Entity
public class Post {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "user_id") // FK column in Post
private User user;
}
1. What Hibernate sees
Post.user→ owner side → has a foreign key columnuser_idinPosttable. ✅User.posts→ OneToMany without mappedBy → Hibernate thinks this is a separate unidirectional relationship.
💡 Important: Hibernate does not know that User.posts is the inverse of Post.user.
2. What Hibernate does
- Creates an extra join table for the
User.postscollection.
By default, Hibernate might name it: user_posts
| user_id | posts_id |
| 1 | 101 |
| 1 | 102 |
3. Database tables now
- User table
| id | name |
| 1 | Alice |
| 2 | Bob |
- Post table (FK from ManyToOne)
| id | title | user_id |
| 101 | Post1 | 1 |
| 102 | Post2 | 1 |
- Join table (
user_posts) created by OneToMany without mappedBy
| user_id | posts_id |
| 1 | 101 |
| 1 | 102 |
4. Why does this happen
Without
mappedBy, Hibernate treatsUser.postsas another independent relationship.It cannot reuse the
user_idinPostbecause it doesn’t know they are the same relationship.So it creates a join table to safely store the mapping.
✅ Key takeaway:
mappedBytells Hibernate: use the foreign key in Post → no extra table.Without
mappedBy→ Hibernate creates a join table even if a foreign key already exists in Post.