I have this Entity class with nickname String as a key.
@Data
@Entity
@Table(name="players")
public class Player {
@Id
private String nickname;
@Column(name="name")
private String name;
@Column(name="surname")
private String surname;
...
...
...
}
Controller
@PostMapping(value="/addPlayer", consumes = {MediaType.APPLICATION_JSON_VALUE}, produces ={MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<Player> save(@RequestBody Player player) throws Exception {
return new ResponseEntity<>(playerService.save(player), HttpStatus.OK);
}
Service (interface)
Player save(Player player) throws Exception;
Service Impl
@Override
public Player save(Player player)throws Exception{
if(player.getName() != null && (!player.getName().isEmpty() && (!player.getName().isBlank())) &&
(player.getSurname() != null && (!player.getSurname().isEmpty() && (!player.getSurname().isBlank()))) &&
(player.getNickname() != null && (!player.getNickname().isEmpty() && (!player.getNickname().isBlank())))) {
return playerRepository.save(player);
}
throw new IllegalArgumentException("provide name,surname and nickname");
}
Repository
@Repository
public interface PlayerRepository extends JpaRepository<Player, String> {
//somestuff
}
I have this situation in DB.
If I try this request :
then in DB i have this bad behavior
Data are overwrite on key " nickname5
"
work like a patch 🙁 , I don’t understand how and why.
I try to add unique annotation at nickname column but not work …
@Id
@Column(unique = true)
private String nickname;
Can I ask why i have this behavior and how I can fix it ?
(yes I can do manually with some check in a service but I think I miss some annotation or functionality about data-jpa-framework)
Other than this bug, if you see things that are not right or things that can be done better in the code, I welcome suggestions. I am here to improve .
Thank you !
@Edit
I have add the unique constraint on ‘nickname’ pk – uk
But behavior is the same. Name and Username are update if I pass a Nickname(primary-key) already in the database
2
Answers
You are using a nickname as a primary key in your table. While you’ve annotated it with @Id JPA makes it a primary key and it is unique.
As for your save() method, here it checks whether the object is present or not in DB if yes then update or else create.
In your application.yml add
then you can see the SQL query run by JPA to know how it actually works
As we discussed into comments this is my answer and some explanation about your case:
First of all you have to avoid using
String
as primary key because in this case because when you are going to add new use withreturn playerRepository.save(player);
and a row with the same value as primary key is already persisted to database it will do update instead to throw exception, becausesave()
method fromJpaRepository
work so.In your case you should have something like this one approach:
Entity:
Database Table:
And when you will try to persist a value that already exist in database with the same
nickname
:You will have the next one exception: