-------采用SQL语句查询JPA导致BigInteger cannot be cast to java.lang.Long异常
问题
今天在使用Spring Data JPA时,采用自己书写的一天原生SQL语句来进行数据库查询数据,当时是关联两张表,根据条件来获取符合条件的id,代码如下:
@Query(value = "SELECT community_id FROM t_community_customer_relate WHERE customer_id=:customerId AND community_id NOT IN (SELECT tc.community_id FROM t_blacklist tb LEFT JOIN t_community_customer_relate tc ON tb.customer_id=tc.customer_id WHERE tb.black_customer_id=:customerId AND tc.be_master=1)",nativeQuery = true)
List<Long> findCommunityIds(@Param("customerId") Long customerId);
当我运行代码时,出现了异常:
java.math.BigInteger cannot be cast to java.lang.Long
原因
通过debug才发现获取的到数据是BigInteger类型,并不是我想要的Long类型,debug结果如下:
通过上网查询发现JPA有两个查询方式,一种是通过JPQL语句进行查询的CreateQuery,另外一种是SQL语句查询的CreateSQLQuery;前者查询时以对象数组进行存储,后者以hibernate生成的Bean为对象装入list返回,当实例不存在时它会按照JPA给定的默认配置去返回映射值,而bigint的映射正是BigInteger。而我使用的是SQL进行查询,且返回的数据并无实例对象,所以返回的数据都为BigInteger,不能用Long类型的集合去接收数据;
解决办法
方法1:
编写JPQL语句进行数据查询;
方法2:
依然用SQL进行查询,使用映射的数据类型的集合进行接收:
@Query(value = "SELECT community_id FROM t_community_customer_relate WHERE customer_id=:customerId AND community_id NOT IN (SELECT tc.community_id FROM t_blacklist tb LEFT JOIN t_community_customer_relate tc ON tb.customer_id=tc.customer_id WHERE tb.black_customer_id=:customerId AND tc.be_master=1)",nativeQuery = true)
List<BigInteger> findCommunityIds(@Param("customerId") Long customerId);
然后对集合中的数据进行遍历强转,创建一个新的集合来装载:
List<BigInteger> communityIds = communityCustomerRelateService.findCommunityIds(customerId);
ArrayList<Long> ids = new ArrayList<>();
for (BigInteger communityId : communityIds) {
Long id = (Long) communityId.longValue();
ids.add(id);
}
或者将集合转为Steam流的形式进行再进行转换成Long类型:
List<BigInteger> communityIds = communityCustomerRelateService.findCommunityIds(customerId);
List<Long> ids = communityIds.stream().map(s -> Long.parseLong(s.toString())).collect(Collectors.toList());
网友评论