无法延迟实例化HashMap

时间:2019-04-01 21:05:58

标签: java spring hibernate spring-data-jpa

我有下一个错误:

Request processing failed; nested exception is org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: my.shop.common.fliPusto.origins.User.spectatingBooks, could not initialize proxy - no Session

我尝试使用Hibernate.initialize()myObject.getMyMap().size()初始化Map,但是它们都抛出异常。

我的HashMap课程:

@Entity
@Table(name = "users")
public class User implements UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

...

@ElementCollection(fetch = FetchType.LAZY)
@CollectionTable(name = "spectatingBooks", joinColumns = @JoinColumn(name = 
"user_id"))
@MapKeyJoinColumn(name = "book_id")
@Column(name = "lastChapter")
private Map<Book, Long> spectatingBooks = new HashMap<Book, Long>();
}

当我将抓取类型从“懒惰”更改为“渴望”时,一切正常,但是我认为这是错误的方式。

我的课堂上尝试添加一些书籍:

@Transactional
@Service
public class UserDetailsServiceImpl implements UserDetailsService, 
UserDetailsServiceImplInterface {

...

@Transactional
public Boolean addBookmark(User user, Long bookId) {
    Optional<Book> book = bookRepository.findById(bookId);

    if (book.isPresent()) {
        Hibernate.initialize(user);
        int size = user.getSpectatingBooks().size();    <--Exception
        user.getSpectatingBooks().put(book.get(), 
        Integer.toUnsignedLong(0));
        userRepository.save(user);
        return true;
    }

    return false;
}
}

是否有任何方法可以延迟地实例化HashMap,或者仅适用于Fetch.Eager?

1 个答案:

答案 0 :(得分:0)

我通过让用户通过userRepository而不是@AuthenticationPrinciple来解决它,但是也许还有另一种方法吗?

@Transactional
public Boolean addBookmark(Long userId, Long bookId) {
    Optional<Book> book = bookRepository.findById(bookId);
    Optional<User> userOp = userRepository.findById(userId);

    if (book.isPresent() && userOp.isPresent()) {
        User user = userOp.get();
        int size = user.getSpectatingBooks().size();
        user.getSpectatingBooks().put(book.get(), Integer.toUnsignedLong(0));
        userRepository.save(user);
        return true;
    }

    return false;
}