Spring jpa генерирует ClassCastException при использовании пользовательских запросов - PullRequest
0 голосов
/ 16 марта 2019

Я пытаюсь получить только определенный набор столбцов из запроса, однако я получаю ClassCastException.

2019-03-16 00:03:19.321 ERROR 8440 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to com.metadata.entity.FileItem] with root cause

java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to com.metadata.entity.FileItem
    at com.metadata.service.FileItemService.findFileWithVersion(FileItemService.java:39) ~[classes/:na]
    at com.metadata.service.FileItemService$$FastClassBySpringCGLIB$$7a805cbb.invoke(<generated>) ~[classes/:na]
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.1.4.RELEASE.jar:5.1.4.RELEASE]

Вот самые основы моей структуры.

FileItem

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.CreationTimestamp;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import java.util.Date;
import java.util.UUID;

@Entity
@IdClass(FileItemId.class)
@Table(name = "files")
@AllArgsConstructor
@NoArgsConstructor
@Data
public class FileItem {

    @Id
    private UUID id;

    @Id
    private long version;

    @Column(name = "total_size")
    private long totalSize;

    private String name;
    private byte[] file;

    @CreationTimestamp
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "created_at")
    private Date createdAt;
}

FileItemId.java

import lombok.Data;
import java.io.Serializable;
import java.util.UUID;

@Data
public class FileItemId implements Serializable {
    private UUID id;
    private Long version;
}

FileItemRepository

import com.metadata.entity.FileItem;
import com.metadata.entity.FileItemId;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;

import java.util.List;
import java.util.UUID;

public interface FileItemRepository extends JpaRepository<FileItem, UUID> {
    @Query("select f.id, f.version, f.name, f.totalSize, f.createdAt " +
            "from FileItem f " +
            "where f.id = ?1 and f.version = ?2")
    List<FileItem> findByFileIdAndVersion(UUID id, Long version);

}

Ответы [ 2 ]

1 голос
/ 16 марта 2019

Я давно не использовал JPA, но, похоже, ваш запрос возвращает массив Object []

Тогда подпись вашего метода должна быть:

@Query("select f.id, f.version, f.name, f.totalSize, f.createdAt " +
            "from FileItem f " +
            "where f.id = ?1 and f.version = ?2")
    Object[] findByFileIdAndVersion(UUID id, Long version);

В противном случаеесли вы хотите сохранить подпись вашего метода:

@Query("select f " +
            "from FileItem f " +
            "where f.id = ?1 and f.version = ?2")
    List<FileItem> findByFileIdAndVersion(UUID id, Long version);

Другое решение:

@Query("select new com.mycompany.mypackage.MyDTO(f.id, f.version, f.name, f.totalSize, f.createdAt) " +
            "from FileItem f " +
            "where f.id = ?1 and f.version = ?2")
    MyDTO findByFileIdAndVersion(UUID id, Long version);

Где MyDTO - это пользовательский Java-бин, который вы пишете для своих нужд.

0 голосов
/ 16 марта 2019

Я нашел решение, используя прогнозы весной.Однако я не уверен, что это лучшее решение.

FileItemNoBlob

import java.util.Date;
import java.util.UUID;

public interface FileItemNoBlob {
    UUID getId();
    Long getVersion();
    Date getCreatedAt();
    Long getTotalSize();
    String getName();
}

FileItemNoBlob findByIdAndVersion(UUID id, Long version); в хранилище кажется работающим.Было бы лучше создать еще один репозиторий для проекционных классов, чтобы он стал чище.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...