Как исправить получение повторяющейся записи при обновлении Entity JpaRepository

Я пытаюсь обновить старую запись файла в своей базе данных новым объектом. Essential Я сохраняю исходный объект файла в БД, а затем обновляю новый объект с соответствующей информацией, сохраненной в БД (включая идентификатор, который является первичным ключом). Но когда я пытаюсь сохранить новую сущность, я получаю org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [md5_UNIQUE]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement. Я вижу, что это не работает, и я доказал себе, что информация копируется правильно в журналах. Я предполагаю, что мне не хватает чего-то, почему он не обновляет информацию.

До того, как я добавил первое сохранение, он работал, но из-за отсутствия УНИКАЛЬНОГО идентификатора для столбца MD5 он вызывал дубликаты, но я изменил это и добавил начальное сохранение, чтобы оно не зашло так далеко, что файл уже сохранен раньше он пойман базой данных. По сути, это просто проверка в начале.

Это мой абстрактный обработчик:

public abstract class AbstractFileResolver {

    @Autowired private FileRepository fileRepository;

    protected abstract File processUpload(MultipartFile file, File entity) throws Exception;
    protected abstract File found(File file);

    public File upload(MultipartFile file) throws Exception {

        String md5 = DigestUtils.md5Hex(file.getInputStream());
        File found = fileRepository.findOneByMd5(md5);

        if (null != found) return found(found);

        File newFile = null;
        try {
            File f = new File();
            f.setMd5(md5);
            newFile = fileRepository.save(f);
            return processUpload(file, newFile);
        } catch (Exception e) {
            LOG.error("There was an error processing upload.", e);
            if (newFile != null) fileRepository.delete(newFile);
            throw e;
        }
    }
}

Это мой реализованный обработчик:

public class JpegImageFileResolverImpl extends AbstractFileResolver {

    @Autowired private FileRepository fileRepository;
    @Autowired private ImageMetaData imageMetaData;
    @Autowired private PropertiesBean properties;

    @Override
    protected File processUpload(MultipartFile file, File entity) throws Exception {
        Jpeg model = (Jpeg) imageMetaData.loadImage(file, new Jpeg());
        model.setFilePath(imageMetaData.generateNewFilePath(model));
        java.io.File uploadedFile = new java.io.File(properties.rootDirectory + model.getFilePath());
        FileUtils.writeByteArrayToFile(uploadedFile, file.getBytes());
        model.setId(entity.getId()); // setting the import info
        return fileRepository.save(model); // this is the error
    }
}

Это моя файловая сущность:

@Entity
@Table(name = "files")
@Inheritance(strategy=InheritanceType.JOINED)
public class File {

    @Id
    @Column(name = "file_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id = 0;

    @Column(name = "md5")
    private String md5 = "";

    @Column(name = "uploaded")
    private Timestamp uploaded;

    // Getters and setters

}

Это мой объект Jpeg:

@Entity
@Table(name = "jpegs")
public class Jpeg extends AbstractImage {

    @Column(name = "quality", nullable=false)
    private String quality = "";

    @Column(name = "optimized", nullable=false)
    private boolean optimized = false;

    // Getters and setters
}

Это мое абстрактное изображение:

@Entity
@Table(name = "images")
public class AbstractImage extends File{

    @Column(name = "dpi", nullable=false)
    private int dpi = 0;

    // Getter and setter
}

Ожидаемый результат состоит в том, что при первоначальном сохранении таблица будет выглядеть примерно так:

| file_id |               md5              | Timestamp |
|---------|--------------------------------|-----------|
| 1       |033f6535fa99857722f43301e68d8b82| null      |

Но после того, как вся работа будет завершена, при втором сохранении он должен выглядеть так:

| file_id |               md5              | Timestamp |
|---------|--------------------------------|-----------|
| 1       |033f6535fa99857722f43301e68d8b82| 2019-01-03|

Но, как я уже говорил выше, мне кажется, что это просто не работает или, может быть, работает, и я что-то упускаю. Если я что-то упускаю, что мне не хватает? Если это не сработает, как вы посоветуете обойти проблему?

Я пытаюсь обновить старую запись файла в своей базе данных новой сущностью так что подразумевается для File found(File file)? Означает ли Но когда я пытаюсь сохранить новую сущность ... объект исходный или нашел (& обновленный)?
pirho 05.01.2019 11:37

@pirho found - это просто обходной путь. Он получит объект jpeg из репозитория, используя найденный file. Если вы следуете processUpload, он берет новый объект jpeg и загружает его с информацией о файле. Затем я копирую MD5 и file_id, затем вызываю save для нового объекта jpeg. Однако на самом деле я просто пытаюсь обновить информацию о файле в таблице новой информацией, следовательно, копирую идентификатор как попытку обновить информацию в таблице.

C. Smith 05.01.2019 18:12
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Версия Java на основе версии загрузки
Версия Java на основе версии загрузки
Если вы зайдете на официальный сайт Spring Boot , там представлен start.spring.io , который упрощает создание проектов Spring Boot, как показано ниже.
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
0
2
795
0

Другие вопросы по теме