У меня имеется такая вот сущность:
@Data
@Entity
public class Message {
@Id
private long id;
private String recipient;
private String subject;
private String text;
private boolean sent;
private String status;
@Column(name = "expire")
@CreationTimestamp
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh:mm:ss")
private Date expire;
@Column(name = "updated_at")
@CreationTimestamp
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh:mm:ss")
private Date updatedAt;
@Column(name = "created_at")
@CreationTimestamp
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh:mm:ss")
private Date createdAt;
@PreUpdate
protected void onUpdate() {
updatedAt = new Date();
}
}
И такой тестовый контроллер:
@RestController
public class MessageTestController {
@Autowired
private MessageService messageService;
@RequestMapping("/testMessage")
public Message testMessage(@RequestBody Message message) {
System.out.println(message.getId());
System.out.println(message.getRecipient());
System.out.println(message.getStatus());
System.out.println(message.getSubject());
messageService.save(message);
return messageService.findById(0);
}
}
Проблема в том, при отправке контроллеру json
в таком формате
{
"id": 0,
"recipient": "samoilov.s@natalie-tours.ru",
"subject": "some subject",
"text": null,
"sent": false,
"status": "NOT NOW 2",
"expire": "2017-06-27 09:42:41",
"updatedAt": "2017-06-27 09:48:27",
"createdAt": "2017-06-27 09:42:41"
}
возникает такая ошибка
ERROR: duplicate key value violates unique constraint "message_pkey"
Но если я сделаю messageService.findById(0)
и потом save
полученного элемента, то update
произойдет успешно. Почему так ?
Если над id
поставить аннотацию @GeneratedValue(strategy=GenerationType.IDENTITY)
, то будет происходить insert
новых записей с новым id
, но не update
. При этом в json
я передаю id
напрямую.
когда Вы делаете сначала messageService.save(message);, то объект message неперсистный, а new (или Transient) и HIBERNATE полагает, что Вы создали новый объект и в БД его нет. Поэтому Hibernate делает insert. Он не делает предварительную проверку есть ли объект с ID=0 в БД. А когда Вы сначала сделаете find, то HIBERNATE создаст в кэше персистный объект с ID=0 и при save будет понимать, что объект с id=0 уже есть и надо делать update.
Попробуйти использовать утилиту, для просмотра содержимого кэша перед и после вызовов этих двух методов в разных порядках.
Содержимое кэша
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
При создании записи в БД через crud-приложение java кириллические символы в таблице юзеров (crud по юзерам) и в БД (в MySQLWorkbench) отображаются приблизительно...
ЗдравствуйтеЕсть текст моя программа делит его на предложения