由网友(毫无意义)分享简介:JPA:方法@Repositorypublic interface FloorRepository extends JpaRepository {@Query("select distinct tnFloor from TnFloor tnFloor where tnFloor....
JPA:方法
@Repository
public interface FloorRepository extends JpaRepository<TnFloor, Integer> {
@Query("select distinct tnFloor from TnFloor tnFloor where tnFloor.tnBuilding.buildingId in ?1")
public List<TnFloor> findByBuildingIds(List<Integer> buildingIds);
}
@Before("dataRolesPointCuts()")
public void beforeMethods(JoinPoint joinPoint) {
log.debug(" Before Advice Called " + joinPoint.toShortString());
String classArray[]=joinPoint.getTarget().getClass().getGenericInterfaces()[0].getTypeName().split(".");
String className = classArray[classArray.length-1];
String methodName = joinPoint.getSignature().getName();
String securedMethodName = className + "_" + methodName;
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if(authentication!=null)
{
UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();
String loggedINUserName = userDetails.getUsername();
Map<String, Map<String, String>> userRoleMap = usernameRoleMap.get(loggedINUserName);
TnMethodSecurityModel methodSecurity = methodSecurityMap.get(securedMethodName); // Replace with Map
if(methodSecurity!=null && methodSecurity.getTnMethodSecurityFilters()!=null && methodSecurity.getTnMethodSecurityFilters().size()>0)
{
Class<?> clazz =((Class<?>) joinPoint.getTarget().getClass().getGenericInterfaces()[0]);
try {
Method[] methods = clazz.getMethods();
Method method=null;
for(Method meth: methods )
{
if(meth.getName().equals(methodName))
{
method=meth;
break;
}
}
if(method == null)
return;
Query secParam = method.getAnnotation(Query.class);
String query=secParam.value();
String securityPredicate=Util.getSecuirtyPredicate(methodSecurity, userRoleMap);
try {
System.out.println("old MethodAnnotation = " + secParam.value());
Util. changeAnnotationValue(secParam, "value", query+" "+securityPredicate);
System.out.println("Asspect Query :: "+query);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("modified MethodAnnotation = " + secParam.value());
} catch ( SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
log.info("Executing with argument: {}", className + " " + methodName);
}
@SuppressWarnings("unchecked")
public static Object changeAnnotationValue(Annotation annotation, String key, Object newValue){
Object handler = Proxy.getInvocationHandler(annotation);
Field f;
try {
f = handler.getClass().getDeclaredField("memberValues");
} catch (NoSuchFieldException | SecurityException e) {
throw new IllegalStateException(e);
}
f.setAccessible(true);
Map<String, Object> memberValues;
try {
memberValues = (Map<String, Object>) f.get(handler);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
Object oldValue = memberValues.get(key);
if (oldValue == null || oldValue.getClass() != newValue.getClass()) {
throw new IllegalArgumentException();
}
memberValues.put(key,newValue);
return oldValue;
}
建议执行前输出:
old MethodAnnotation = select distinct tnFloor from TnFloor tnFloor where tnFloor.tnBuilding.buildingId in ?1
modified MethodAnnotation = select distinct tnFloor from TnFloor tnFloor where tnFloor.tnBuilding.buildingId in ?1 (tnFloor.tnBuilding.buildingId IN (0,1,6))
但最终JPA正在执行修改前的查询输出:。
select tnbuilding0_.building_id as building1_17_0_, tnbuilding0_.description as descript2_17_0_, tnbuilding0_.name as name3_17_0_, tnbuilding0_.site_id as site_id4_17_0_, tnsite1_.site_id as site_id1_65_1_, tnsite1_.description as descript2_65_1_, tnsite1_.email as email3_65_1_, tnsite1_.name as name4_65_1_, tnsite1_.url as url5_65_1_ from tn_building tnbuilding0_ inner join tn_site tnsite1_ on tnbuilding0_.site_id=tnsite1_.site_id where tnbuilding0_.building_id=?
推荐答案
很抱歉给您上课,但是...注释值是常量。您无法更改它们。您尝试更改它们在内存中的表示形式的老套方法可能是一种巧妙的练习,但糟糕的设计。如果您的应用程序或方面确实依赖于这样的东西,作为开发人员,您应该立即感受到重构的冲动。
至于为什么它不能像您想象的那样工作:您可能会认为,在执行带注释的方法之前,Spring每次都会读取注释。但通常这样的框架会在连接应用程序时扫描注释。
简单地说,对于您可能希望通过使用AOP或其他方式使其更具动态化的东西,不要使用硬编码常量(如在注释中)。如果您确实希望保留查询注释,但使用AOP,我认为您应该尝试挂钩到另一个组件,在该组件中,查询正在被解析或发送到数据库,并在那里进行修改。相关推荐
最新文章