#java #mysql #hibernate #mariadb #jhipster
#java #mysql #спящий режим #mariadb #jhipster
Вопрос:
У меня есть проект с Hibernate 5.2.17.Final и Java 8 с MariaDB.
У моей сущности есть byte[]
поле, в котором я сохраняю файл в БД. После того, как я использовал это поле для отправки файла в S3, я хочу удалить его содержимое (установив для него значение null), а затем сохранить объект в БД с этим полем, установленным в null
.
Мне нужно сохранить этот столбец в базе данных, поскольку это обновление, и для этого столбца есть записи с ненулевым значением.
Что я пробовал:
// first this:
invoiceDTO.setPdf(null);
// as the value of "PDF" is already null, invoice will have it also null
Invoice invoice = invoiceFaMapper.toEntity(invoiceDTO);
invoice = invoiceFaRepository.save(invoice);
При отладке поле имело значение null, но значение в базе данных не равно null.
// then I tried this:
byte[] pdf = null;
invoice.setPdf(pdf);
что также оставило меня с ненулевым значением в БД, опять же, при отладке invoice
имело ненулевое значение.
// last thing I tried was:
invoice.setPdf("".getBytes());
Опять же, это не было null.
Чего мне не хватает?
РЕДАКТИРОВАТЬ: После invoice = invoiceFaRepository.save(invoice);
этого указывается значение для byte[]
поля.
Если я выполняю отладку и не тороплюсь, для поля устанавливается значение null, если нет точки прерывания, для него будет установлено не значение null, а предыдущее значение.
Я даже пробовал это после того, как уже сохранил его, чтобы сделать его нулевым, но безрезультатно.
invoice.setPdf(null);
invoiceFaRepository.save(invoice);
ПРАВКА2: Invoice.java (актуально)
(...)
@Lob
@Column(name = "pdf")
private byte[] pdf;
(...)
public byte[] getPdf() {
return pdf;
}
public Invoice pdf(byte[] pdf) {
this.pdf = pdf;
return this;
}
public void setPdf(byte[] pdf) {
this.pdf = pdf;
}
Комментарии:
1. Вы проверили, не получаете ли вы дубликат в базе данных? Один со старым значением и один с null?
2. если вы имеете в виду, что в БД может быть другой столбец, то нет, есть только один столбец, содержащий такое значение
3. Не столбец, я имею в виду другую запись в таблице.
4. нет, я создаю новые записи, чтобы проверить, является ли значение null или нет, ни одна из новых записей не
5. Пожалуйста, вставьте подробный код
Invoice
класса
Ответ №1:
После сохранения объекта в БД я перенаправляю на этот объект. Поскольку в счете-фактуре много строк, я запрашиваю que invoice и его строки
Optional<InvoiceDTO> invoiceDTO = invoiceService.findOneWithLines(id);
Внутри этого метода у меня было что-то вроде этого:
@Override
public Optional<InvoiceFaDTO> findOneWithLines(long id) {
Optional<Invoice> i = invoiceFaRepository.findById(id);
i.ifPresent(invoice -> {
if (invoice.getAttachmentUrl() != null) {
invoice.setPdf(amazonService.downloadFile(invoice.getAttachmentUrl()).toByteArray());
}
});
return i.map(invoiceFaMapper::toDto);
}
дело в том, что все, что я делаю внутри скобок, сохраняется в БД, и я не знаю почему (я не вызываю репозиторий, так зачем это сохранять?).
Я решил проблему, отредактировав поле вне i.ifPresent(invoice -> {
строки.
РЕДАКТИРОВАТЬ: Service
класс был аннотирован с помощью @Transactional
, добавление @Transactional(readOnly = true)
действительно решило проблему.