EntityNotFoundException 和MultipartException相关处理

最近在论坛上加入了附件上传的功能,踩了几个坑,这里做一下整理。网上很多的帖子都是你抄我我抄你,也不知道问题解决了没有,反正就发到自己博客上面,一个字不拉的抄过来。有什么意思呢?别人搜索的时候全是一样的废信息,给大家找到真正的解决方法,带来很大困扰。

1.EntityNotFoundException: Unable to find Person with id 11

1)项目里使用了JPA+hibernate,在级联查询时都使用的对象属性映射,主题是一个对象,附件是一个对象,主题中有一个附件集合对象,映射关系是一对多。我一开始使用的是中间表的形式,因为附件上传时,主题还没有创建,所以不能做关联。

    @OneToMany(cascade = CascadeType.MERGE, fetch = FetchType.EAGER)
	@Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)
	@JoinTable(name = "topic_attach", joinColumns = { @JoinColumn(name = "topic_id") }, inverseJoinColumns = {
			@JoinColumn(name = "attach_id") })
	@JsonIgnore
	private Set<Role> attachs= new HashSet<>();

在附件上传完成,保存主题时,在一个中间表中保存对应关系。

2)第一次上传附件保存主题,没有问题。对附件进行删减后,再保存就报了上面的错误。我已开始以为是事务问题,比如说附件保存主题的时候,附件信息没有提交导致查询不到。后来把hibernate的show-sql设为true,打印了语句才发现,原来是映射关系有问题,在保存映射关系时会查询一下这个附件的信息,但是由于映射关系的问题,这个查询语句经过七七八八的关联,确实没有查出来这个附件信息。

3)问题确认了,我对对象之间的关系没有理解清楚,百度搜这个异常,给的都是一堆有的没的解决办法。最后找到一个介绍hibernate对象映射设计的博客,重新定义映射关系,取消了中间表(可以减少生成的sql语句的关联层数,从而减少不必要的错误,毕竟hibernate自动生成的语句,你干着急改不了它),改成在附件里面加一个主题id的方式,问题解决。

    @OneToMany(fetch = FetchType.EAGER)
	@Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)
	@JoinColumn(name = "topic_id")
	@JsonIgnore
	private Set<Role> attachs= new HashSet<>();

2.org.springframework.web.multipart.MultipartException,could not parse multipart servlet request;nested exception is ...

1)这个问题根本原因是附件超过了上传的限定,这个限定可以在spring中设置,然后web容器也有它自身的限制,比如tomcat需要在server.xml中进行设置,在Connector节点中增加属性 maxPostSize="52428800" (50M)。要保持一致,避免前后矛盾。

2)出异常不可怕,我们把异常抓到返回给用户,告诉他附件过大,就可以了。现在的问题是,如何拦截到这个异常,在项目中定义的全局异常拦截抓不到它,因为还没有进到我的action中异常已经抛出了,程序就卡在那里了。

3)解决的办法就是推迟文件的解析处理,让它到我们自己的代码时再解析文件,判断大小之类的操作。而不是上传组件早早进行判断、发现问题、抛出异常。对应的springboot中就是增加一个配置项:

@Configuration
public class RequestConfiguration extends WebMvcConfigurerAdapter {
    @Bean
    public MultipartResolver multipartResolver(){
        CommonsMultipartResolver resolver = new CommonsMultipartResolver();
        resolver.setDefaultEncoding("UTF-8");
        //resolveLazily属性启用是为了推迟文件解析,自定义捕获文件大小异常
        resolver.setResolveLazily(true);
        return resolver;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值