JPA LazyInitialisationException - не удалось инициализировать прокси - PullRequest
0 голосов
/ 11 февраля 2019

Да, я видел похожие вопросы, но ни один из ответов на самом деле не привел меня к решению.Я нигде не использую этот поток, и этот же код работает в другом приложении jhipster, поэтому я озадачен, почему этот lift + shift вызывает проблемы Hibernate.

public UserDetailsContextMapper userDetailsContextMapper() {
    return new UserDetailsContextMapper() {
        @Override
        public UserDetails mapUserFromContext(
            DirContextOperations ctx, String username,
            Collection<? extends GrantedAuthority> authorities) {
            log.error("2 " + username + " -> " + ctx.toString());
            String lowercaseLogonName = username.toLowerCase();
            Optional<User> userFromDatabase = userRepository.findOneByLogin(lowercaseLogonName);
            if (!userFromDatabase.isPresent()) {
                User ldapUser = new User();
                ldapUser.setLogin(lowercaseLogonName);
                ldapUser.setPassword(RandomStringUtils.random(60)); // We use LDAP password, but the password need to be set
                ldapUser.setActivated(true);
                try {
                    Attribute attribute = ctx.getAttributes().get("mail");
                    ldapUser.setEmail( attribute != null && attribute.size() > 0 ? (String) attribute.get(0) : "");
                    attribute = ctx.getAttributes().get("givenname");
                    ldapUser.setFirstName(attribute != null && attribute.size() > 0 ? (String) attribute.get(0) : "");
                    attribute = ctx.getAttributes().get("sn");
                    ldapUser.setLastName(attribute != null && attribute.size() > 0 ? (String) attribute.get(0) : "");
                } catch (NamingException e) {
                    log.warn("Couldn't get LDAP details for user: " + lowercaseLogonName);
                }

                Set<Authority> newUserAuthorities = new HashSet<>();
                Authority authority = authorityRepository.getOne(AuthoritiesConstants.USER);

                newUserAuthorities.add(authority); <-- This line in the Exception

                ldapUser.setAuthorities(newUserAuthorities);
                ldapUser.setLangKey("en");
                userRepository.saveAndFlush(ldapUser);

            }

Исключение:

org.hibernate.LazyInitializationException: could not initialize proxy [com.app.my.let.domain.Authority#ROLE_USER] - no Session
        at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:155)
        at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:268)
        at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:73)
        at com.app.my.let.domain.Authority_$$_jvst758_1e.hashCode(Authority_$$_jvst758_1e.java)
        at java.util.HashMap.hash(HashMap.java:339)
        at java.util.HashMap.put(HashMap.java:612)
        at java.util.HashSet.add(HashSet.java:220)
        at com.app.my.let.config.SecurityConfiguration$1.mapUserFromContext(SecurityConfiguration.java:249) <-- code line above

Свойства JPA:

jpa:
        database-platform: org.hibernate.dialect.SQLServer2012Dialect
        database: SQL_SERVER
        show_sql: true
        format_sql: true
        properties:
            hibernate.id.new_generator_mappings: true
            hibernate.cache.use_second_level_cache: false
            hibernate.cache.use_query_cache: false
            hibernate.generate_statistics: true

РЕДАКТИРОВАТЬ - Это решило мою проблему:

Optional<Authority> optAuthority = authorityRepository.findById(AuthoritiesConstants.USER);

Authority authority = optAuthority.get();

1 Ответ

0 голосов
/ 11 февраля 2019

Эта строка:

Authority authority = authorityRepository.getOne(AuthoritiesConstants.USER);

дает вам только ссылку на сущность.Под капотом он называет EntityManager#getReference.Говорят, что это не сущность, а просто ссылка для целей объектно-реляционного отображения.Исключение выдается, потому что вы пытаетесь привести его за пределы транзакционной среды.

Есть несколько решений.Чтобы получить сущность, вам нужно будет использовать EntityManager#find или сделать это в транзакции (используйте @Transactional вместо метода).Здесь вы также можете вызвать Hibernate.initialize(authority) для извлечения сущности из базы данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...