场景:系统对应不同省份,可以不属于任何省份
JpaRepository的实现直接扩展了extends JpaRepository<T,ID>,JpaSpecificationExecutor<T>
因此要调整left join,BZ的实现:
实现改为:
要求:省份表为基础数据,仅系统的查询关联
实现:
系统BEAN:(多的一方)
/**
* all,remove,refresh,merge,persist:删除,更新,合并,查找
*/
@ManyToOne(cascade={CascadeType.PERSIST},optional=false)
@JoinColumn(name="PROVINCE_ID",nullable=true,insertable=false,updatable=false)
@NotFound(action=NotFoundAction.IGNORE)
private UniflowProvince uniflowProvince;
省份BEAN:(一的一方)
/**
* 系统信息列表
*/
@OneToMany(cascade={CascadeType.PERSIST//Cascade detach operation
/*,CascadeType.PERSIST*/
},
fetch = FetchType.LAZY, //EAGER急加载,加载一个实体时,定义急加载的属性会立即从数据库中加载。
mappedBy="uniflowProvince"//关系维护
)
@NotFound(action=NotFoundAction.IGNORE)
private List<CollectorSystem> collectorSystems;
JpaRepository的实现直接扩展了extends JpaRepository<T,ID>,JpaSpecificationExecutor<T>
在系统不属于任何省份时,如果直接调用findOne根据Id来查询,打印出来的SQL语句为:
select * FROM
MSS.COLLECTOR_SYSTEM collectors0_
INNER JOIN
MSS.UNIFLOW_PROVINCE uniflowpro1_
ON
collectors0_.PROVINCE_ID=uniflowpro1_.PROVINCE_CODE
WHERE
collectors0_.ID=?
采用的是
INNER
这样就会出现如下错误信息:
严重: Servlet.service() for servlet assembler threw exception
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'bean' available as request attribute
at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:141)
因此要调整left join,BZ的实现:
public CollectorSystem getEntityById(final long ID) throws SpringRunBizException {
final Specification<CollectorSystem> specification = new Specification<CollectorSystem>(){
public Predicate toPredicate(final Root<CollectorSystem> root,final CriteriaQuery<?> query, final CriteriaBuilder cb) {
final List<Predicate> list = new ArrayList<Predicate>();
list.add(cb.equal(root.get("ID"), ID));
root.join(root.getModel().getSingularAttribute("uniflowProvince",UniflowProvince.class),JoinType.LEFT);//关联查询
final Predicate[] predicates = new Predicate[list.size()];
return cb.and(list.toArray(predicates));
}
};
final CollectorSystem collectorSystem = collectorSystemRepository.findOne(specification);
// final CollectorSystem collectorSystem = collectorSystemRepository.findOne(ID);
return collectorSystem;
}
关联删除的时候,出现如下错误:
java.lang.IllegalArgumentException: The entity must not be null!
at org.springframework.util.Assert.notNull(Assert.java:112)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.delete(SimpleJpaRepository.java:142)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.delete(SimpleJpaRepository.java:132)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:333)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:318)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.data.jpa.repository.support.LockModeRepositoryPostProcessor$LockModePopulatingMethodIntercceptor.invoke(LockModeRepositoryPostProcessor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:91)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
实现改为:
final CollectorSystem collectorSystem = new CollectorSystem();
collectorSystem.setID(id);
collectorSystem.setUniflowProvince(null);
collectorSystemRepository.delete(collectorSystem);
// collectorSystemRepository.delete(id);
通过实体,把一方设置为null