5 Eylül 2023 Salı

SpringData JPA Hibernate Dirty Check

Örnek
Elimizde şöyle bir kod olsun
@Service
public class UserService {

  @Autowired
  private UserRepository userRepository;
  ...
}
Example 1
Şöyle yaparız
// 1. Regular update within a transaction (without explicit saving)
@Transactional
public void updateName(Long userId, String newName) {
  User user = userRepository.findById(userId)alo .orElseThrow(() -> new EntityNotFoundException("User not found"));
  user.setName(newName);
  // Thanks to dirty checking, changes will be saved automatically upon transaction // completion.
}
Example 2
Şöyle yaparız
// 2. Data retrieval without a transaction (changes won't be saved automatically)
public void nonTransactionalUpdateName(Long userId, String newName) { User user = userRepository.findById(userId) .orElseThrow(() -> new EntityNotFoundException("User not found")); user.setName(newName); // Changes will not be saved as the method is not within a transaction. }
Example 3
Şöyle yaparız
// 3. Explicitly saving changes within a transaction
@Transactional public void explicitSaveAfterUpdate(Long userId, String newName) { User user = userRepository.findById(userId) .orElseThrow(() -> new EntityNotFoundException("User not found")); user.setName(newName); // Explicitly saving changes, although it's not required in this context. userRepository.save(user); }
Example 3 içi açıklama şöyle
In this example, explicit saving is not required because Hibernate’s “dirty checking” considers changes in managed entities and automatically synchronizes them with the database at the end of the transaction.

If you still call userRepository.save(user); for a managed entity, in most cases, it won’t lead to any direct negative consequences, but there are a few things to note:

Performance: The save call can potentially trigger additional operations, such as merging entities, which may be less efficient than simply waiting for automatic saving of changes at the end of the transaction.

Code readability: Explicitly calling save for entities that are already in the Hibernate management context can confuse developers unfamiliar with the code context. They might wonder why explicit saving is happening here.

Save behavior: In practice, save in Spring Data JPA works as persist or merge depending on the state of the entity. If the entity is new, it will be saved as a new record, if the entity already exists (for example, it was fetched from the database), it will be merged. In most scenarios, this won’t cause problems, but knowing this behavior is essential for understanding some more complex cases.

Therefore, although explicitly saving managed entities is not an error, it is better to avoid it unless there is a specific need to simplify the code and improve its performance.
Example 4
Şöyle yaparız
// 4. Creating a new entity and saving it
@Transactional
public void createUser(String name, String email) {
  User user = new User();
  user.setName(name);
  user.setEmail(email);
  userRepository.save(user);  // Save is necessary here as the entity is new.
}
Example 5
Şöyle yaparız
// 5. Retrieving data in read-only mode
@Transactional(readOnly = true) public List<User> getAllUsers() { return userRepository.findAll(); // As the method is wrapped in @Transactional with readOnly=true, // any attempts to change entities within this method will not result in their saving // to the DB. }
Example 6
Şöyle yaparız
// 6. Explicitly detaching an entity from the persistence context and then saving it
@Transactional public void detachAndUpdate(Long userId, String newName) { User user = userRepository.findById(userId)alo .orElseThrow(() -> new EntityNotFoundException("User not found")); userRepository.detach(user); // Detaching the entity from the persistence context. user.setName(newName); // Now we need to explicitly save changes as the entity is detached. userRepository.save(user); }

Hiç yorum yok:

Yorum Gönder