Spring Boot - 数据JPA - 从DB下载大型Lob文件

时间:2017-03-25 06:04:46

标签: java hibernate rest spring-boot spring-data-jpa

我已经编写了一个spring boot web / rest应用程序来处理遗留系统(DB表),该应用程序执行以下操作:

  1. 用户通过REST WS创建帐单请求。
  2. 我的其他应用程序将请求存储到旧版数据库表。
  3. 另一个系统(X)(我的控制)读取记录并生成一个zip文件。
  4. X系统然后将文件存储在我们的表中(zip文件和文件名)。
  5. 用户现在可以使用我的应用程序下载文件。
  6. 这里的问题是一些账单文件很大(1-2 GB)而且我得到了:

    java.lang.OutOfMemoryError: Java heap space
    
    当我试图选择文件内容

    时,这会发生在Hibernate中

    现在如何让用户下载大文件而不会出现上述错误?请在下面查看POJO课程和Repos

    实体类

    @Entity
    public class EbillStatus implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    @Id @GeneratedValue(generator="system-uuid")
    @GenericGenerator(name="system-uuid", strategy="uuid")  
    @Column(name="EBILL_STATUS_ID")
    private String id;
    
    @Column(name="CORPORATE_EBILL_ID", insertable=false, updatable=false)
    private String corporateEbillId;
    
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name="COMPLETION_DATETIME")
    private Date completionDatetime;
    
    @Column(name="FILENAME", insertable=false, updatable=false)
    private String filename;
    @Lob
    private byte[] fileContent;
    
    @Column(name="USER_ID")
    private String username;
    
    @Column(name="STATUS_ID")
    private Integer status;
    
    @Column(name="BILL_COUNT", insertable=false, updatable=false)
    private Integer billCount;
    
    private Integer accountCount;
    }
    

    存储库:

    public interface EbillStatusRepository extends JpaRepository<EbillStatus, String> {
    EbillStatus findByCorporateEbill(CorporateEbill corporateEbill);
    
    @Query(value="select s FROM EbillStatus s WHERE s.corporateEbillId=?1")
    EbillStatus findFile(String corporateEbillId);
    }
    

    服务方法实施:

    @Service
    public class EbillServiceImpl implements EbillService {
    
    private EbillStatusRepository statusRepo;
    
    @Autowired
    public EbillServiceImpl(EbillStatusRepository statusRepo){
        this.statusRepo = statusRepo;
    }
    
    @Override
    public EbillFileModel getEbillFile(String username, String eBillId) throws NotFoundException{
        EbillStatus ebill= statusRepo.findFile(eBillId);
        if(ebill == null || !isEbillFileAvailable(ebill.getStatus()))
            throw new NotFoundException("file not available for username: "+username+", eBillId: "+ eBillId);
        return new EbillFileModel(ebill.getFilename(), ebill.getFileContent());
    }
    
    private boolean isEbillFileAvailable(Integer status){
        return COMPLETED.equals(String.valueOf(status)) || DELIVERED.equals(String.valueOf(status));
    }
    }
    

    给控制器的Pojo类

    public class EbillFileModel {
    private String fileName;
    private byte[] fileContent;
    public EbillFileModel(String fileName, byte[] fileContent) {
        super();
        this.fileName = fileName;
        this.fileContent = fileContent;
    }
    public EbillFileModel() {
        super();
    }
    public String getFileName() {
        return fileName;
    }
    public void setFileName(String fileName) {
        this.fileName = fileName;
    }
    public byte[] getFileContent() {
        return fileContent;
    }
    public void setFileContent(byte[] fileContent) {
        this.fileContent = fileContent;
    }   
    }
    

    下载文件的控制器方法

    @GetMapping(value = "/{username}/order/{eBillId}/download", produces = "application/zip")
    public ResponseEntity<ByteArrayResource> downloadEbillFile(@PathVariable String username, @PathVariable String eBillId)
            throws IOException, NotFoundException {
        EbillFileModel file = ebillservice.getEbillFile(username, eBillId);     
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.CACHE_CONTROL, CACHE_CONTROL_VAL);
        headers.add(HttpHeaders.PRAGMA,PRAGMA_VAL);
        headers.setContentDispositionFormData(ATTACHMENT, file.getFileName());
        headers.add(HttpHeaders.EXPIRES, ZERO);
        return ResponseEntity
                .ok()
                .headers(headers)
                .contentType(APPLICATION_ZIP)
                .body(new ByteArrayResource(file.getFileContent()));
    }
    

    摘要和注释:

    • 我无法改变系统设计及其工作原理,我只是在它上面写了一个Web / REST应用程序。
    • 我使用的是Spring boot 1.5.1.RELEASE和java 8
    • 打包是在JBoss EAP 7上部署的WAR文件
    • 下载存储在DB中的大文件的最佳方法是什么。

0 个答案:

没有答案