开发常见问题整理
JPA
- parallelStream 调用 manyToMany 清除关联关系无效
1 |
|
这里使用基于注解的 Spring 事物,Spring 中大量使用基于代理的模式来处理方法调用,如果被代理对象实现了接口则使用 JDK 动态代理
,未实现接口则使用 CGLIB 代理
,通过代理在方法调用时获取注解进行事物处理,实际在方法处理中会使用 AOP 切面编程来处理不同切入点的事件,具体的两个实现类为 CglibAopProxy
和 JdkDynamicAopProxy
,切面的不同切入点 advice
又维护一系列的拦截方法 MethodInterceptor
,通过方法调用时适合的拦截器会开始工作,比如我们这里的 TransactionInterceptor
会为方法调用包裹事物。
为什么并行流中的操作未其作用?原因在与并行流中的操作会使用 Fork/Join
被 ForkJoinTask
来执行,而该对象并没有受 Spring 代理的控制,所以在其中的方法调用并不会受注解的作用,即使我们声明了需要开启新事物。
更好的方法是使用手动事物:
1 | public void clearAuthorBooks() { |
- Java11 集成 querydsl 报 javax.annotation.api not found
For those who are still fighting with the issue and when all proposed workarounds don’t work, here is what helped me (Java 11):
1 | // querydsl |
Taken from https://stackoverflow.com/questions/50537096/annotationprocessor-and-dependencies
This combination taken from #2459 (comment) also works:
1 | configure(querydslProjects) { |
Docker
Devops
- Jar 包加载 ClassPath 下的文件报找不到文件
JAR 代表 Java ARchive - 归档,它是一种包文件格式,通常用于将许多 Java 类文件和关联的元数据和资源聚合到一个文件中以进行分发。JAR 文件是包含 Java 特定清单文件的存档文件。它们以 ZIP 格式构建,通常具有 .jar 文件扩展名。
当我们使用 Spring 的 ClassPathResource("files/filename")
访问文件资源时,正常开发的情况下文件位于系统文件系统中,可以正常访问;当打成 JAR 包发布访问时,由于处在 JAR 特殊的 ZIP 包中,调用 getFile
将抛出错误,因为它不属于文件系统的文件。
虽然不能直接获取文件,但是还是可以通过类加载器访问到文件流或者 URL,getInputStream()
或 getURL
。
Java
- Collectors.toMap valueMapper 为 null 导致 NPE
Collectors.toMap 的 keyMapper 和 valueMapper 都不允许为 null,不管实际提供的 Map 实现是否支持 null。
它在内部使用 Map.merge,这是 JDK 的一个 open bug。
可以使用下面的写法收集流或者原始的写法:
1 | Map<Integer, Boolean> collect = list.stream() |