Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 禁用SpringBoot应用程序上的OpenIn视图时,Eclipse或SpringBoot能否帮助我找到需要事务的方法?_Java_Spring_Eclipse_Spring Boot_Spring Tool Suite - Fatal编程技术网

Java 禁用SpringBoot应用程序上的OpenIn视图时,Eclipse或SpringBoot能否帮助我找到需要事务的方法?

Java 禁用SpringBoot应用程序上的OpenIn视图时,Eclipse或SpringBoot能否帮助我找到需要事务的方法?,java,spring,eclipse,spring-boot,spring-tool-suite,Java,Spring,Eclipse,Spring Boot,Spring Tool Suite,我有一个相当新的SpringBootJava应用程序,我正在开发,我没有意识到SpringJPA“在视图中打开”的默认设置是打开的 我遇到了一些问题,禁用该设置最终是最好的解决方案,但现在我遇到了一些我意外依赖它的案例 例如,我有一个未标记为@Transactions的服务类,在返回控制器之前,它在我的一个实体的惰性初始化子级上循环 现在,正如预期的那样,这个函数抛出LazyInitializationException,因为我不在事务中 我还没有编写提供100%覆盖率的测试用例,Eclipse

我有一个相当新的SpringBootJava应用程序,我正在开发,我没有意识到SpringJPA“在视图中打开”的默认设置是打开的

我遇到了一些问题,禁用该设置最终是最好的解决方案,但现在我遇到了一些我意外依赖它的案例

例如,我有一个未标记为@Transactions的服务类,在返回控制器之前,它在我的一个实体的惰性初始化子级上循环

现在,正如预期的那样,这个函数抛出LazyInitializationException,因为我不在事务中

我还没有编写提供100%覆盖率的测试用例,Eclipse、Sprint Tools Suite或Spring Boot运行时中是否内置了任何我可以生成报告的内容,以告诉我何时使用@Entity注释的类在非事务性方法调用中对它们进行了函数调用

有没有其他方法来尝试识别这一点,而不向我的应用程序添加100%的代码覆盖率测试,或者仔细检查每个方法调用

如果没有,那么我将处理测试用例


感谢您的指导。

这并不完美,但我确实找到了一种方法,使用
反射
库查找我的应用程序的大多数案例。我将此作为
@SpringBootTest
测试用例运行,并一次修复一个错误

@Test
public void testOne() throws NoSuchMethodException, SecurityException{
    Reflections reflections = new Reflections("my.base.package",
                        new SubTypesScanner(), 
                          new TypeAnnotationsScanner(),
                          new MemberUsageScanner());

    Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(javax.persistence.Entity.class);

    for( Class<?> c: annotated){
        log.debug(c.getSimpleName());
        for( Method m: c.getMethods()){
            if( m.getReturnType().isAnnotationPresent(Entity.class) ){
                checkTransactional(reflections,c, m, 0);
            }
        }
    }
   Assert.assertTrue(true);
}

public static void checkTransactional(Reflections reflections, Class<?> c, Method m, int depth) throws NoSuchMethodException, SecurityException{
    if( depth >64){
        throw new RuntimeException("No Transactional Method Found");
        //return;
    }
    String s = "--";
    Annotation t = null;

    Class<?>[] possibleAnnotations = {
            org.springframework.transaction.annotation.Transactional.class,
            javax.transaction.Transactional.class, 
    };

    Annotation[] annotations = m.getAnnotations();
    for( Annotation a: annotations){
        Class<?> aClass = a.annotationType();
        //// handle javax and spring Transactional
        if( aClass.getSimpleName().equals("Transactional")){
            t = a;
            s = "++";
            break;
        }
    }


    String prefix = "";
    for( int i = 0; i < depth; i++){
        prefix = prefix + s;
    }

    log.debug( prefix + " " + c.getCanonicalName() + ":" + m.getName());

    if( t != null ){
        log.trace("This is transactional");
        return;
    }

    Set<Member> callingMembers = reflections.getMethodUsage(m);
    if( callingMembers.size() == 0){
        log.error("Nothing calls this method, if it is a controller, we have a problem" + (c.isAnnotationPresent(Controller.class) || c.isAnnotationPresent(RestController.class)));
        if( (c.isAnnotationPresent(Controller.class) || c.isAnnotationPresent(RestController.class)) ){
            throw new RuntimeException("No transactional method found in call heirrchy before controller"); 
        }
    }
    for( Member usingMember: callingMembers){
        Class<?> callingClass = usingMember.getDeclaringClass();
        List<Method> callingMethods = new ArrayList<Method>();
        if( callingClass != c ){
            for( Method callingClassMethod: callingClass.getMethods()){
                if( callingClassMethod.getName().equals(usingMember.getName())){
                    callingMethods.add(callingClassMethod);
                }
            }   
        }
        if( callingMethods.size() > 2){
            log.error("Two methods call this, manually review");
            for( Method caller: callingMethods){
                log.debug( prefix + "!! " + c.getCanonicalName() + ":" + caller.getName() + ":" + caller.getParameterCount());
            }
            throw new RuntimeException("Two methods with same name ( overloading ) call this, manually review"); 

        }
        for( Method caller: callingMethods){
            checkTransactional(reflections, callingClass, caller, depth+1);
        }
    }
}
@测试
public void testOne()抛出NoSuchMethodException、SecurityException{
反射=新反射(“my.base.package”,
新的子扫描程序(),
新类型AnnotationsCanner(),
新成员UsageScanner());
设置[]可能的注释={
org.springframework.transaction.annotation.Transactional.class,
javax.transaction.Transactional.class,
};
Annotation[]annotations=m.getAnnotations();
对于(注释a:注释){
类aClass=a.annotationType();
////处理javax和spring事务
if(aClass.getSimpleName().equals(“事务”)){
t=a;
s=“+”;
打破
}
}
字符串前缀=”;
for(int i=0;i2){
log.error(“两种方法调用此,手动查看”);
for(方法调用方:callingMethods){
log.debug(前缀+“!!”+c.getCanonicalName()+”:“+caller.getName()+”:“+caller.getParameterCount());
}
抛出新的RuntimeException(“两个同名的方法(重载)调用此,手动检查”);
}
for(方法调用方:callingMethods){
检查事务性(反射、调用类、调用方、深度+1);
}
}
}

我严重怀疑是否存在这样的工具。如果可以通过编程来检查事务边界的正确性,甚至可以提供帮助,我们就知道了。你可能会发现一些简单的案例(假设很重),但作为一个普遍的解决方案…不。