JPA hibernate 基于注解的级联

场景:系统对应不同省份,可以不属于任何省份

要求:省份表为基础数据,仅系统的查询关联


实现:

系统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

猜你喜欢

转载自blog.csdn.net/xiazou/article/details/43021779