如何让jpa 持久化时不校验指定字段
源文:https://www.toocruel.net/jpa-validate/
怎么让jpa 持久化时不校验指定字段
本文提供全流程,中文翻译。
Chinar 坚持将简单的生活方式,带给世人! (拥有更好的阅读体验 —— 高分辨率用户请根据需求调整网页缩放比例) |
Chinar —— 心分享、心创新!
助力快速完成jpa 持久化时不校验指定字段/文字 为新手节省宝贵的时间,避免采坑! |
- 1
- Problem —— 问题/需求
- 2
- Wrong again —— 错误重现
- 3
- SoluTion —— 解决方案
- 支持
- May Be —— 搞开发,总有一天要做的事!
全文高清图片,点击即可放大观看 (很多人竟然不知道)
1
Problem —— 问题/需求
spring data jpa ,使用了 validate 校验
校验直接加在了要持久化实体类上,为了方便简洁并没有使用 DTO 做验证
但是有的校验仅在 Controller 层需要校验,持久化时不需校验
因为我把他声明为 @Transient 的了,如下 User 类:
/// <summary>
/// 用户类
/// </summary>
public class User {/*** 用户名*/@NotBlank(message = "用户名不能为空")private String username;/*** 密码*/private String password;/*** 角色id*/@NotEmpty(message = "角色id不能为空")@Transientprivate Long[] roleIds;/*** 用户的所有角色*/@ManyToMany(cascade = CascadeType.DETACH)@JoinTable(name = "user_role_relation",joinColumns = @JoinColumn(name = "userId"),inverseJoinColumns = @JoinColumn(name = "roleId"))@JsonIgnoreProperties("users")private Set<Role> roles = new HashSet<>();//...省略 gets and sets
}
其中, roleIds 属性是 Transient 的,表明了不做持久化
我用它只是在 Controller 接收 form 表单提交时要校验
校验通过存入 roles 属性,并不需要在持久化时校验
(但是 jpa 规范或者说 Hibernate 在持久化时会校验所有属性包括 Transient 的)
2
Wrong again —— 错误重现
执行 userRepository.save(new User()), 报错:
javax.validation.ConstraintViolationException: Validation failed for classes [net.toocruel.iqismart.entity.User] during persist time for groups [javax.validation.groups.Default, ]
List of constraint violations:[ConstraintViolationImpl{interpolatedMessage='角色id不能为空', propertyPath=roleIds, rootBeanClass=class net.toocruel.iqismart.entity.User, messageTemplate='角色id不能为空'}
]at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:138) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreInsert(BeanValidationEventListener.java:78) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]at org.hibernate.action.internal.EntityIdentityInsertAction.preInsert(EntityIdentityInsertAction.java:197) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:75) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:619) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:273) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:254) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:299) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:317) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:272) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:178) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:109) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]at org.hibernate.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId(JpaPersistEventListener.java:67) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:189) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:132) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:58) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:775) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:748) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:753) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1146) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]at sun.reflect.GeneratedMethodAccessor190.invoke(Unknown Source) ~[na:na]at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_131]at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_131]at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:298) ~[spring-orm-4.3.10.RELEASE.jar:4.3.10.RELEASE]at com.sun.proxy.$Proxy145.persist(Unknown Source) ~[na:na]at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:508) ~[spring-data-jpa-1.11.6.RELEASE.jar:na]at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_131]at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_131]at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_131]at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_131]at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:504) ~[spring-data-commons-1.13.6.RELEASE.jar:na]at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:489) ~[spring-data-commons-1.13.6.RELEASE.jar:na]at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:461) ~[spring-data-commons-1.13.6.RELEASE.jar:na]at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.10.RELEASE.jar:4.3.10.RELEASE]at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:56) ~[spring-data-commons-1.13.6.RELEASE.jar:na]
...
...
3
SoluTion —— 解决方案
从上面关键错误信息:
Validation failed for classes [net.toocruel.iqismart.entity.User] during persist time for groups [javax.validation.groups.Default, ]
可以看到,虽然给roleIds加了@Transient注解,JPA仍旧进行了校验,还发现有个groups:
[javax.validation.groups.Default, ]
原来,jpa validate 是可以分组校验,默认的有个组default,持久化时要校验这个组 , 不指定时就是默认的
比如,roleIds的@NotEmpty(message = "角色id不能为空")
未指定groups,那它就是默认组的,持久化时会被校验的。
由此,有了一个想法,把roleIds的校验组不使用默认,而是设置为另一个组,这样似乎可行。
于是,修改User roleIds的校验注解:
@NotEmpty(message = "角色id不能为空",groups = ControllerGroup.class)
@Transient
private Long[] roleIds;
增加了groups = ControllerGroup.class
,其中 ControllerGroup 是随便新建一个类或接口都可以。
至此:如期所料,完美解决!
支持
May Be —— 搞开发,总有一天要做的事!
拥有自己的服务器,无需再找攻略!
Chinar 提供一站式教程,闭眼式创建! 为新手节省宝贵时间,避免采坑! |
先点击领取 —— 阿里全产品优惠券 (享受最低优惠)
1 —— 云服务器超全购买流程 (新手必备!)
2 —— 阿里ECS云服务器自定义配置 - 购买教程(新手必备!)
3—— Windows 服务器配置、运行、建站一条龙 !
4 —— Linux 服务器配置、运行、建站一条龙 !
![](/assets/blank.gif)
技术交流群:806091680 ! Chinar 欢迎你的加入
END
本博客为非营利性个人原创,除部分有明确署名的作品外,所刊登的所有作品的著作权均为本人所拥有,本人保留所有法定权利。违者必究
对于需要复制、转载、链接和传播博客文章或内容的,请及时和本博主进行联系,留言,Email: ichinar@icloud.com
对于经本博主明确授权和许可使用文章及内容的,使用时请注明文章或内容出处并注明网址>
转载于:https://www.cnblogs.com/chinarbolg/p/9601410.html
如何让jpa 持久化时不校验指定字段相关推荐
- SpringBoot使用JPA多表关联动态查询指定字段
SpringBoot使用JPA多表关联动态查询指定字段 目标需求 Maven依赖 项目结构 代码 运行结果 源码下载 目标需求 在SpringBoot中用JPA实现多表关联动态查询,并且只查询指定字段 ...
- mybatis 需要注意的点 MyBatis 插入空值时,需要指定JdbcType (201
转自:https://blog.csdn.net/snakemoving/article/details/76052875 前天遇到一个问题 异常显示如下: 引用 Exception in threa ...
- 使用JPA获取Oracle中的日期字段丢失时分秒
2019独角兽企业重金招聘Python工程师标准>>> 使用JPA获取oracle中的日期字段发现没有时分秒,因为之前没有关注过这个字段, 最近由于需要,却发现时分秒奇怪的丢失. ...
- Android 软键盘弹出时布局内指定内容上移实现及问题解决
Android 软键盘弹出时布局内指定内容上移实现及问题解决 参考文章: (1)Android 软键盘弹出时布局内指定内容上移实现及问题解决 (2)https://www.cnblogs.com/as ...
- JPA持久化异常:PersistenceException: org.hibernate.PersistentObjectException
1.PersistenceException异常如下 javax.persistence.PersistenceException: org.hibernate.PersistentObjectExc ...
- Redis在持久化时产生的延迟
点击上方"朱小厮的博客",选择"设为星标" 做积极的人,而不是积极废人 一个老外的有关Redis的博客文章中提到一个有趣的事情:它们在测试期间获得的延迟图.为了 ...
- 【oracle】关于创建表时用default指定默认值的坑
刚开始学create table的时候没注意,学到后面发现可以指定默认值.于是写了如下语句: 当我查询的时候发现,查出来的结果是这样的.. 很纳闷有没有,我明明指定默认值了呀,为什么创建出来的表还是空 ...
- mysql触发器 当记录的指定字段发生变化时,更新表中的另外一个字段,或者更新另外一张关联表中关联记录的字段...
2019独角兽企业重金招聘Python工程师标准>>> 注意:语句中出现的old,new,now(),都为数据库自带的关键字,此处不做解释. 两种情况: 第一种:一张表中,更新某条记 ...
- Easyui validatebox修改——1.当text发生变化时在校验,2.取消校验,3扩展自定义验证
1.当text发生变化时在校验: Easyui validatebox个人感觉还是比较好用的,但是发现他不是只有text改变并离开编辑框的时候才验证,而是不停的做验证:如果是js脚本的本地验证还好,如 ...
- html file 隐藏,input type=file /浏览时只显示指定文件类型(html5新特性)
type="file" />浏览时只显示指定文件类型 accept属性列表 1.accept="application/msexcel" 2.accept ...
最新文章
- git 裁切_裁切参数设计(DOE试验)
- 李德毅院士:希望智能驾驶成为我国继高铁之后又一张新名片
- php mssql 端口,MSSQL_SQL Server端口更改后的数据库连接方式,SQL Server端口,大家可以通过quot - phpStudy...
- 最远的你是我最近的爱
- C# 创建Windows服务。服务功能:定时操作数据库
- MyBatisPlus的ActiveRecord实现CRUD
- nas php.ini,php.ini 配置文件常用详解
- 阿里云混合云联合信通院发布《基于云计算的数字化业务安全工程要求》
- python表达式3 5_python3 第五章 - 什么是变量、运算符、表达式
- java 创建类带泛型_java-创建泛型类列表
- PHP 二维数组根据某个字段排序
- Atitit 前端测试最简化内嵌web服务器 php 与node.js 目录 1.1. php内置Web Server	1 1.2. Node的	2 Node的比较麻烦些。。Php更加简单
- 浅谈人工智能 | 语音识别面面观
- 香港恒生银行App下载
- GDAL综合整理--7:GDAL实用工具简介
- 二代身份证读取 中控ID180 二三代身份证阅读器 Vue版本
- Flutter开发日常练习-小猫咪杂货店(新增欢迎页,广告页和侧滑页面)
- 古代益智游戏汉诺塔java解决
- Launcher中拨号、短信图标加数字提示未接电话、未读短信数量
- leaflet实现风场流动
热门文章
- 软件工程师证书怎么考_2020年想考一个证书,考一级造价工程师还是考咨询工程师?...
- 8数据提供什么掩膜产品_喜茶、茶百道、书亦、古茗8月外卖热销产品数据全解析...
- 模拟京东登陆 java_java-爬虫部分:关于京东模拟登陆的两种实现 | 学步园
- 学数值计算可以从事计算机算法吗,数值计算方法
- java redis设置过期时间_Redis的内存回收原理,及内存过期淘汰策略详解
- c++用两个队列实现一个栈
- 不解之缘———我与Linux系统
- Java千百问_05面向对象(008)_java中覆盖是什么
- 根据模板提示,加入元素,修改CSS
- ARM64移动处理器解惑