CRUD Operation
1. Question and Concepts
1.1 @Transactional with Hibernate
- opens a transaction before method execution and commits/rolls back after.
- Executes Hibernate operations (INSERT/UPDATE/DELETE).
- Without @Transactional : insert may not execute (no commit), or may hit
LazyInitializationException.
1.2 save()
save() does two things: insert or update
- If the object is new : it will insert it into the database.
- If the object already exists : it will update the existing record.
How does it know if it’s new or existing?
It looks at the ID field (@Id):
- ID is null or not in DB → new → insert
- ID exists in DB → update
1.3 Why Hibernate runs SELECT before INSERT?
- Manual ID / merge() → check if entity exists or not.
- ID generation Strategy(AUTO, TABLE, SEQUENCE).
- Relationship checks (@ManyToOne, @OneToOne).
sql: insert into user (id, name,email) values (1, 'a','a@gmail.com');
Hibernate: select u1_0.uid,u1_0.email,u1_0.name from user u1_0 where u1_0.uid=?
Hibernate: insert into user (email,name,uid) values (?,?,?)
1.4 Custom / Dervied findBy method
Rules
- Define abstract methods in the repository.
- Format:
findBy<EntityClassPropertyName>(DataType propertyArgumentName). - Return type: allow zero or more records.
- Property name: first letter uppercase after
findBy.
Entity
@Entity
public class User{
private String name;
@Column(name="email")
private String emailAddress;
}
Repository
public interface UserRepository extends JpaRepository<User, Integer> {
List<User> findByName(String n);
List<User> findByEmailAddress(String e);
List<User> findByNameAndEmailAddress(String e,String n);
List<User> findByNameOrEmailAddress(String e,String n);
}
2. Insert
save()
- SQL:
- Inserts a single record.
Example:
saveAll()
- SQL:
- Inserts multiple records at once.
Example:
List<User> users = new ArrayList<>();
users.add(new User(2, "b", "b@gmail.com"));
users.add(new User(3, "c", "c@gmail.com"));
userRepository.saveAll(users);
3. Update
// load and save
public void updateUserById(int id, String email) {
Optional<User> optional = userRepository.findById(id);
if (optional.isPresent()) {
User user = optional.get();
user.setEmail(email);
userRepository.save(user);
}
else System.out.println("No record Found!");
}
4. Read / Select
findAll()
- SQL:
- Returns all records from the table.
Example:
List<User> users = userRepository.findAll();
users.forEach(u -> {
System.out.println(u.getId()+" "+u.getName()+" "+u.getEmail());
});
findById()
- SQL:
- Always points to the identifier column of the entity.
- Returns single record wrapped in
Optional<T>no record may be present.
Example:
Optional<User> userOptional = userRepository.findById(1L);
if (userOptional.isPresent()) {
User u = userOptional.get();
System.out.println(u.getId() + " " + u.getName() + " " + u.getEmail());
} else {
System.out.println("User not found!");
}
5. Delete
deleteById
- The method does not return anything.
- should check record existence ( with
existsById) before calling it to avoid exceptions.
public boolean deleteUserById(int id) {
if (userRepository.existsById(id)) {
userRepository.deleteById(id);
return true; // deleted
}
return false; // not found
}
Github Code : CRUD Operation