I have problem with Hibernate. I have next method:
@Override
public Task assignedUser(Long taskId, Long userId) {
final Task taskBeforeUpdate = taskRepository.findById(taskId);
if (Objects.isNull(taskBeforeUpdate)) {
throw new TaskNotFoundException("Cannot assign, because task with id " taskId " was not found");
}
if (!Objects.isNull(taskBeforeUpdate.getUser())) {
throw new BadRequestException("User cannot assigned on task with id " taskId " because task already have user ");
}
final User user = userRepository.findById(userId);
final Task assignedTask = taskRepository.assignUser(taskBeforeUpdate.getId(), user.getId());
kafkaSenderTaskProducer.sendUpdatedEvent(assignedTask,taskBeforeUpdate);
return assignedTask;
}
This method should assign user on task and send message to kafka consumer with TaskBeforeUpdate and TaskAfterUpdate. But I have problem when I try to assign user, my BeforeUpdateTask change all his fields to TaskAfterUpdate. And this dont work, but i dont know why he is change all values.
public Task assignUser(Long taskId, Long userId) {
log.debug("AssignUser.E with Task id: {} and User id: {}", taskId, userId);
try {
tx.begin();
Task task = entityManager.find(Task.class, taskId);
User user = entityManager.find(User.class, userId);
task.setUser(user);
final Task updatedTask = entityManager.merge(task);
tx.commit();
if (Objects.isNull(updatedTask)) {
log.warn("AssignUser.X with null");
return null;
}
log.debug("AssignUser.X with Task: {}", updatedTask);
return updatedTask;
} catch (final HibernateException ex) {
tx.rollback();
throw new TaskDAOException("Cannot crate user", ex);
}
}
@Override
public Task findById(Long id) throws TaskDAOException {
log.debug("FindById.E with Task id: {}", id);
tx.begin();
final Task task = entityManager.find(Task.class, id);
tx.commit();
if (Objects.isNull(task)) {
log.warn("FindById.X with null");
return null;
}
log.debug("FindById.X with Task: {}", task);
return task;
}
CodePudding user response:
The EntityManger manages all attached Entities. And an Entity is unique by its Id. So basically if you load a entity twice with its ID you get the same object. Not just an equal object, its really the same.
One you can remove the taskBeforeUpdate from the Entity Manager before taskRepository.assignUser this should solve the problem
entityManager.detach(taskBeforeUpdate);
Or I would map the taskBeforeUpdate object into an other object of a different class which is then passed to kafkaSenderTaskProducer.sendUpdatedEvent (Data Transfer Object)