Reputation: 77
Suppose I have a user class:
@Entity
@Data
@Builder
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
Long userKey;
@Column(unique = true)
String someId;
String name;
}
And it's corresponding service
@Component
@Slf4j
public class UserService {
@Autowired
UserRepository repository;
@Transactional
public User createUserWithId(String name, String id) {
User userToAdd = User.builder()
.name(name)
.someId(id)
.build();
repository.save(userToAdd);
log.info("No issue in saving");
//some more code
return userToAdd;
}
}
As you can see that I have a unique constraint on someId field in User class but when I execute the method createUserWithId with a value in someId which is already present in DB, I'd expect to get an error on the line containing repository.save() and the code after it to not be executed. But the code after it is getting executed and I'm getting an exception at the end of the transactional block. My question is why this is happening and what are the exceptions which I would generally get when interacting with the repository object ( like in this case repository.save ) and which type of exceptions will I get at the end of transactional block ?
PS I am calling the UserService from inside a simple controller and I have created an empty UserRepository which just extends CrudRepository. Both of which I have left out from the question for brevity but let me know if adding them here would make sense.
EDIT 1: Adding user repository as per request in comments
@Repository
public interface UserRepository extends CrudRepository<User, Long> {
}
Upvotes: 0
Views: 4387
Reputation: 63
When we call
repository.save(obj);
hibernate kept this entity in memory, the Entity will persist at the of the method in the Transaction.
One more way to do such kind of operation, first you should try to fetch result on id
repository.findById(id)
And check whether it is null or not and accordingly perform save operation.
Upvotes: 0
Reputation: 16452
The error happens in the interceptor because right before committing the transaction, Hibernate needs to flush pending changes to the database. During that flush, the database exception happens. You can flush manually by calling saveAndFlush
on the repository.
Upvotes: 2
Reputation: 2587
Uniqe error happens when duplicate . spring has database error helper class that you can catch db exceptions on controller layer passed by @transactional to controller.
} catch (DataAccessException ex) {
or
} catch (DataIntegrityViolationException ex) {
in case the database connector has standard exception throw support.
in your case I think you missed
@Transactional(readOnly = false)
Upvotes: 0