Проблема с конвертацией потока данных BYTEA в таблицу Postgres в Docker контейнере(+ Spring)

При попытке мой локально рабочий Spring Boot + Postgres проект развернуть через Docker-Compose получаю ошибку во время попыток загрузить какой-либо документ в БД.

Имею сущность файла с такими полями


@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@EntityListeners(AuditingEntityListener.class)
@ToString(exclude = { "data" })
public class FileEntity implements BaseEntity, Authorable, Available {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String filename;
    private String filetype;

    @Lob
    @Column(columnDefinition = "BYTEA")
    private byte[] data;

    @ManyToOne(fetch = FetchType.EAGER)
    @JsonProperty("author")
    @JoinColumn(name = "author_id")
    private User author;

    @JsonProperty(value = "public_file_entity", defaultValue = "false")
    private Boolean publicEntity = false;

    @JsonProperty(value = "available_for")
    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinTable(
            name = "file_entity_user_access",
            joinColumns = @JoinColumn(name = "id_file_entity"),
            inverseJoinColumns = @JoinColumn(name = "id_user",
                    foreignKey = @ForeignKey(name = "fk_file_entity_user",
                            foreignKeyDefinition = "FOREIGN KEY (id_user) REFERENCES users(id_user) ON DELETE CASCADE"))
    )
    @JsonIgnore
    private Set<User> availableFor = new HashSet<>();

    @CreatedDate
    @Column(updatable = false)
    private LocalDate creationDate;

    @LastModifiedDate
    @Column(insertable = false)
    private LocalDate updateDate;
}

Ниже мой контроллер, сервисный слой


    @PostMapping("/upload")
    public FileEntity uploadFile(
            @RequestParam("file") MultipartFile file,
            @RequestPart("params") String paramsJson
    ) throws IOException
    {
        ObjectMapper objectMapper = new ObjectMapper();
        FileEntityUpdateDTO paramsDTO = objectMapper.readValue(paramsJson, FileEntityUpdateDTO.class);

        log.info("получили файл с параметрами {}", file.getOriginalFilename());
        log.info("получили дто с  параметрами {}", paramsDTO.toString());
        return fileService.storeFile(file, paramsDTO);
    }


    @Override
    public FileEntity storeFile(MultipartFile file, FileEntityUpdateDTO paramsDTO) throws IOException {
        FileEntity fileEntity = new FileEntity();
        fileEntity.setFilename(file.getOriginalFilename());
        fileEntity.setFiletype(file.getContentType());
        fileEntity.setData(file.getBytes());
        fileEntity.setAuthor(userUtils.getCurrentUser());

        if (paramsDTO != null && paramsDTO.getPublicEntity()) {
            fileEntity.setPublicEntity(true);
        }
        if (paramsDTO != null && paramsDTO.getAvailableFor() != null && !paramsDTO.getAvailableFor().isEmpty()) {
            fileEntity.setAvailableFor(mappingFromDtoToEntity(paramsDTO.getAvailableFor()));
        }
        log.info("сейчас в сущности файла есть поле с данными файла типа {}", fileEntity.getData().getClass().getSimpleName());

        return fileRepository.save(fileEntity);
    }
    private Set<User> mappingFromDtoToEntity(Set<Long> userIds) {
        if (userIds == null || userIds.isEmpty()) {
            return new HashSet<>();
        }
        return new HashSet<>(userRepository.findAllById(userIds));
    }

Конфигурация docker-compose.yml и application.properties


version: "3.9"

volumes:
  document_accounting:

services:
  document_accounting_db:
    image: postgres
    restart: always
    environment:
      - POSTGRES_USER=ivan
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=document_accounting_db
    volumes:
      - document_accounting:/var/lib/postgresql/data
    ports:
      - "127.0.0.1:5432:5432"

  app:
    restart: always
    build: .
    ports:
      - "8080:8080"
    depends_on:
      - document_accounting_db
    environment:
      SPRING_DATASOURCE_URL: 'jdbc:postgresql://document_accounting_db:5432/document_accounting_db'
      JAVA_OPTS: '-Xmx512m'

____________________________________________________________________

spring.application.name=DocumentAccounting2


spring.jpa.defer-datasource-initialization=true
spring.jpa.show-sql=true
spring.sql.init.mode=always


document_accounting.jwtCookieName=springAuthDemoToken
document_accounting.jwtSecret=0C659Ajwvt95MkZFzrg57TQi5AiHINzC5QINtsYemOeO2ZFQlm
document_accounting.jwtExpirationMs=86400000


spring.thymeleaf.prefix=classpath:/templates/
spring.web.resources.static-locations=classpath:/static/, classpath:/static/html/, classpath:/static/html/files
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML5


#logging.level.root=TRACE
logging.level.org.springframework = DEBUG
logging.file.path=logs/
logging.file.name=logs/application.log
logging.logback.rollingpolicy.max-file-size=10MB
logging.logback.rollingpolicy.max-history=1000

spring.output.ansi.enabled=always

spring.servlet.multipart.max-file-size=50MB
spring.servlet.multipart.max-request-size=50MB

spring.profiles.default=development


#data for start in docker-compose
spring.datasource.url=jdbc:postgresql://localhost:5432/document_accounting_db
spring.datasource.username=ivan
spring.datasource.password=password

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=update

Получаю при загрузке файлов на этот ендпоинт такую портянку

documentaccounting2-app-1                     | 2024-07-24T19:19:51.027Z DEBUG 1 --- [DocumentAccounting2] [io-8080-exec-10] o.s.d.auditing.AuditingHandlerSupport    : Touched FileEntity(id=null, filename=3b68b19a-5634-4bf6-b738-2bf1dfb8f4eb_photo_2024-06-13_10-40-58.jpg, filetype=image/jpeg, author=User(idUser=1, username=admin, [email protected], password=$2a$10$J.hrsOXCPwUQul3E2.Wxsu9MCjjTj2FaQywfXP9Wf6GDMfa/9aQEu, name=Ivan, lastName=null, photo=null, roles=[Role(idRole=1, name=ROLE_ADMIN, creationDate=null, updateDate=null), Role(idRole=3, name=ROLE_USER, creationDate=null, updateDate=null)], creationDate=null, updateDate=null), publicEntity=false, availableFor=[], creationDate=2024-07-24, updateDate=2024-07-24) - Last modification at 2024-07-24T19:19:51.020311885 by unknown
documentaccounting2-app-1                     | Hibernate: insert into file_entity (author_id,creation_date,data,filename,filetype,public_entity) values (?,?,?,?,?,?) returning id
documentaccounting2-app-1                     | 2024-07-24T19:19:51.059Z  WARN 1 --- [DocumentAccounting2] [io-8080-exec-10] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 0, SQLState: 42804
documentaccounting2-app-1                     | 2024-07-24T19:19:51.059Z ERROR 1 --- [DocumentAccounting2] [io-8080-exec-10] o.h.engine.jdbc.spi.SqlExceptionHelper   : ERROR: column "data" is of type bytea but expression is of type bigint
documentaccounting2-app-1                     |   Hint: You will need to rewrite or cast the expression.
documentaccounting2-app-1                     |   Position: 102
documentaccounting2-app-1                     | 2024-07-24T19:19:51.062Z DEBUG 1 --- [DocumentAccounting2] [io-8080-exec-10] o.s.orm.jpa.JpaTransactionManager        : Initiating transaction rollback
documentaccounting2-app-1                     | 2024-07-24T19:19:51.063Z DEBUG 1 --- [DocumentAccounting2] [io-8080-exec-10] o.s.orm.jpa.JpaTransactionManager        : Rolling back JPA transaction on EntityManager [SessionImpl(394680422<open>)]
documentaccounting2-app-1                     | 2024-07-24T19:19:51.064Z DEBUG 1 --- [DocumentAccounting2] [io-8080-exec-10] o.s.orm.jpa.JpaTransactionManager        : Not closing pre-bound JPA EntityManager after transaction
documentaccounting2-app-1                     | 2024-07-24T19:19:51.066Z DEBUG 1 --- [DocumentAccounting2] [io-8080-exec-10] .m.m.a.ExceptionHandlerExceptionResolver : Using @ExceptionHandler com.ivan_degtev.documentaccounting2.handlers.GlobalControllerExceptionHandler#handleDataAccessException(DataAccessException)
documentaccounting2-app-1                     | 2024-07-24T19:19:51.076Z DEBUG 1 --- [DocumentAccounting2] [io-8080-exec-10] o.s.w.s.m.m.a.HttpEntityMethodProcessor  : Using 'application/problem+json', given [*/*] and supported [application/problem+json]
documentaccounting2-app-1                     | 2024-07-24T19:19:51.080Z DEBUG 1 --- [DocumentAccounting2] [io-8080-exec-10] o.s.w.s.m.m.a.HttpEntityMethodProcessor  : Writing [ProblemDetail[type='about:blank', title='Internal Server Error', status=500, detail='Server error, p (truncated)...]
documentaccounting2-app-1                     | 2024-07-24T19:19:51.081Z DEBUG 1 --- [DocumentAccounting2] [io-8080-exec-10] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.dao.InvalidDataAccessResourceUsageException: could not execute statement [ERROR: column "data" is of type bytea but expression is of type bigint<EOL>  Hint: You will need to rewrite or cast the expression.<EOL>  Position: 102] [insert into file_entity (author_id,creation_date,data,filename,filetype,public_entity) values (?,?,?,?,?,?) returning id]; SQL [insert into file_entity (author_id,creation_date,data,filename,filetype,public_entity) values (?,?,?,?,?,?) returning id]]
documentaccounting2-app-1                     | 2024-07-24T19:19:51.081Z DEBUG 1 --- [DocumentAccounting2] [io-8080-exec-10] o.j.s.OpenEntityManagerInViewInterceptor : Closing JPA EntityManager in OpenEntityManagerInViewInterceptor
documentaccounting2-app-1                     | 2024-07-24T19:19:51.081Z DEBUG 1 --- [DocumentAccounting2] [io-8080-exec-10] o.s.web.servlet.DispatcherServlet        : Completed 500 INTERNAL_SERVER_ERROR

Мое непониманию ухудшается тем, что локально все отрабатывает прекрасно. Имею локальный Postgres 16.3, пробовал в docker-compose.yml прописать это изображение image: postgres:16.3 - проблема осталась. Логирование сущности файла на предмет типа данных дало такой результат перед отправкой в базу documentaccounting2-app-1 | 2024-07-24T19:44:08.415Z INFO 1 --- [DocumentAccounting2] [io-8080-exec-10] c.i.d.service.impl.FileServiceImpl : сейчас в сущности файла есть поле с данными файла типа byte[] Пока не понимаю в чем тут дело. Прошу помочь)


Ответы (1 шт):

Автор решения: Ivan Degtev

Я решил эту проблему просто, но без понимания. Где-то на стеке видел совет, что нужно убрать аннотацию @Lob из поля сущности, и оставить только @Column(columnDefinition = "BYTEA").
Это я и сделал, в докере заработало, но появилась новая проблема, о ней в другом вопросе.

→ Ссылка