byte[] не обнуляется после установки для него значения null

#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) действительно решило проблему.