Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.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 Spring引导和fetchType=Lazy_Java_Hibernate_Spring Mvc_Spring Boot_Spring Security - Fatal编程技术网

Java Spring引导和fetchType=Lazy

Java Spring引导和fetchType=Lazy,java,hibernate,spring-mvc,spring-boot,spring-security,Java,Hibernate,Spring Mvc,Spring Boot,Spring Security,我的Spring Boot应用程序中存在延迟初始化问题。我有一个具有lazy字段角色的实体,我在我的Spring Security(UserDetailsService)方法中有LazyInitializationException),但在controller中没有问题。 你能向我解释一下Spring Boot是如何使用fetch=FetchType.LAZY的吗?为什么它不能在Spring SecurityUserDetailsService和控制器方法中工作? 我没有找到这方面的指南。谢谢

我的Spring Boot应用程序中存在延迟初始化问题。我有一个具有lazy字段
角色的实体
,我在我的Spring Security(
UserDetailsService
)方法中有
LazyInitializationException
),但在controller中没有问题。 你能向我解释一下Spring Boot是如何使用
fetch=FetchType.LAZY
的吗?为什么它不能在Spring Security
UserDetailsService
和控制器方法中工作? 我没有找到这方面的指南。谢谢

弹簧靴:

@SpringBootApplication
public class App {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(App.class, args);
    }
}
实体:

@Entity
@Table(name = "users")
@Getter
@Setter
@NoArgsConstructor
public class Users {
    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "Users_Role", joinColumns = @JoinColumn(name = "User_id", referencedColumnName = "id"),
            inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id"))
    private Set<Role> roles = new HashSet<Role>();
}
我有Spring安全用户详细信息服务:

@Service
    public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private Services services;

    @Override
    public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException {
        Users user;
        Users userFetchedViaGet = services.testGetUser();
        Users userFetchedViaCustomMethod = services.getUserByLogin(login);
        Users userFetchedViaFind = services.testFindUser();
        Users userFetchedWithRoles = services.getUserByLoginWithRoles(login);
        try {
            userFetchedViaGet.getRoles().add(new Role("test"));
        } catch (Exception e) {
            e.printStackTrace();//LazyInitializationException: failed to lazily initialize a collection of role: , could not initialize proxy - no Session
        }
        try {
            userFetchedViaCustomMethod.getRoles().add(new Role("test"));
        } catch (Exception e) {
            e.printStackTrace();//LazyInitializationException: failed to lazily initialize a collection of role: , could not initialize proxy - no Session
        }
        try {
            userFetchedViaFind.getRoles().add(new Role("test")); //LazyInitializationException: failed to lazily initialize a collection of role: , could not initialize proxy - no Session
        } catch (Exception e) {
            e.printStackTrace();
        }
        //some code
        }
    }
和我的控制器(所有方法都可以工作!但是必须执行expetion,因为没有会话和延迟获取类型):


您需要一个事务来包装整个事物—在您的facade上—test()方法,这样才能工作,但这并不是一个好的实践

方法是让您的服务将api方法包装到事务中,并返回一个已完全加载的对象(包含所有子节点)。该对象可以是从Users类构造的简单bean,
从对象或甚至是您希望从rest调用返回的字符串中构建的hashmap。

您需要一个事务来包装整个事物—在您的facade上—test()方法,这样才能工作,但这并不是一个好的实践

方法是让您的服务将api方法包装到事务中,并返回一个已完全加载的对象(包含所有子节点)。该对象可以是从Users类构造的简单bean,
从对象甚至是从rest调用返回的字符串生成的hashmap。

您是否尝试过此Hello!那篇文章和我的问题没有任何共同之处。你能设法解决这个问题吗?我也有同样的问题你试过这个吗喂!那篇文章和我的问题没有任何共同之处。你能设法解决这个问题吗?我也有同样的问题喂!默认情况下,事务readOnly中的Spring数据Jpa包装方法(如testGetUser())为true。我在getUserByLoginWithRoles方法中实现了这一点。为什么像“testGetUser”这样的方法在安全类和控制器中不起作用?为什么在控制器中,我没有收到SpringBoot的延迟异常?为什么Spring Boot初始化了我的惰性集合?弹簧靴怎么样?嗨。问题是,事务在使用spring数据方法后立即结束,因为您在用户和角色实体之间使用延迟获取,所以spring数据方法只获取用户而不获取其角色。如果包装在更大的事务上下文中,则应该可以遍历用户角色图并从数据库中获取所有角色。在本例中,如果可能的话,您可以将延迟获取更改为急切获取,或者编写一个简单的hql查询,如果您不想使此连接变得急切,则强制获取此连接。您好!默认情况下,事务readOnly中的Spring数据Jpa包装方法(如testGetUser())为true。我在getUserByLoginWithRoles方法中实现了这一点。为什么像“testGetUser”这样的方法在安全类和控制器中不起作用?为什么在控制器中,我没有收到SpringBoot的延迟异常?为什么Spring Boot初始化了我的惰性集合?弹簧靴怎么样?嗨。问题是,事务在使用spring数据方法后立即结束,因为您在用户和角色实体之间使用延迟获取,所以spring数据方法只获取用户而不获取其角色。如果包装在更大的事务上下文中,则应该可以遍历用户角色图并从数据库中获取所有角色。在本例中,如果可能的话,您可以将延迟获取更改为急切获取,或者编写一个简单的hql查询,如果您不想使此连接变得急切,则强制获取此连接。
@Service
    public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private Services services;

    @Override
    public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException {
        Users user;
        Users userFetchedViaGet = services.testGetUser();
        Users userFetchedViaCustomMethod = services.getUserByLogin(login);
        Users userFetchedViaFind = services.testFindUser();
        Users userFetchedWithRoles = services.getUserByLoginWithRoles(login);
        try {
            userFetchedViaGet.getRoles().add(new Role("test"));
        } catch (Exception e) {
            e.printStackTrace();//LazyInitializationException: failed to lazily initialize a collection of role: , could not initialize proxy - no Session
        }
        try {
            userFetchedViaCustomMethod.getRoles().add(new Role("test"));
        } catch (Exception e) {
            e.printStackTrace();//LazyInitializationException: failed to lazily initialize a collection of role: , could not initialize proxy - no Session
        }
        try {
            userFetchedViaFind.getRoles().add(new Role("test")); //LazyInitializationException: failed to lazily initialize a collection of role: , could not initialize proxy - no Session
        } catch (Exception e) {
            e.printStackTrace();
        }
        //some code
        }
    }
@RequestMapping(value = "/test", method = RequestMethod.GET)
    public String test() {      
        Users userFetchedViaGet = services.testGetUser();
        Users userFetchedViaCustomMethod = services.getUserByLogin("ADMIN");
        Users userFetchedViaFind = services.testFindUser();
        Users userFetchedWithRoles = services.getUserByLoginWithRoles("ADMIN");
        try {
            userFetchedViaGet.getRoles().add(new Role("test"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            userFetchedViaCustomMethod.getRoles().add(new Role("test"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            userFetchedViaFind.getRoles().add(new Role("test"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        //some code
    }