Java 转换休眠列表而不初始化它

Java 转换休眠列表而不初始化它,java,spring,hibernate,Java,Spring,Hibernate,我有两个实体:牌组和牌 @Entity class Deck { private String name; @ManyToMany private List<Card> cards; } @Entity class Card { private String name; @ManyToMany private List<Deck> decks; } 这段代码的问题是,当我在CardModel中转换Card时,我会触发

我有两个实体:牌组和牌

@Entity
class Deck {
    private String name;

    @ManyToMany
    private List<Card> cards;
}

@Entity
class Card {
    private String name;

    @ManyToMany
    private List<Deck> decks;
}
这段代码的问题是,当我在
CardModel
中转换
Card
时,我会触发与我正在转换的牌组相关的所有卡的延迟加载,但我希望稍后在应用程序中决定是否要提取与
牌组相关的所有


有没有一种简单/标准的方法可以做到这一点?

由于列表中的模型不同,您需要迭代for循环并手动设置它。 由于模型字段不同,您不能使用反射。 否则,您可以使用BeanUtils.copyProperties()将DeckEntity的字段映射到Deck中
并在列表中设置该组对象。

您可以提前验证是否通过以下方法初始化了惰性hibernate集合:

冬眠

例如:

CardModel convert(Card card) {
    CardModel model = new CardModel();
    if (Hibernate.isInitialized(deck.getDecks())) {
         model.setName(card.getName());
         model.setDecks(deck.getDecks().stream()
            .map(deck -> convert(deck))
            .collect(Collectors.toList()));
    }
    return model;
}

通过使用它,您可以验证它的状态,如果没有初始化,只返回空列表。

这是我为自己的问题实现的解决方案,可能对其他人有用

我已经创建了一个
LazyList
对象,它需要一个
ListInitializer
,在第一次操作中
LazyList
将调用
ListInitializer
,它将返回一个
List
,然后,
LazyList
将所有操作委托给从
ListInitializer
返回的
List
。在我的特定情况下,
ListInitializer
将转换并返回已转换的
列表
。因此,如果永远不会使用
LazyList
,则不会转换我的
List

public class LazyList<T> implements List<T> {

    private final ListInitializerSingleton<T> singleton;

    public LazyList(ListInitializer<T> initializer) {
        this.singleton = new ListInitializerSingleton<>(initializer);
    }

    @Override
    public int size() {
        return singleton.list().size();
    }

    @Override
    public boolean isEmpty() {
        return singleton.list().isEmpty();
    }

    @Override
    public boolean contains(Object o) {
        return singleton.list().contains(o);
    }

    @NotNull
    @Override
    public Iterator<T> iterator() {
        return singleton.list().iterator();
    }

    @NotNull
    @Override
    public Object[] toArray() {
        return singleton.list().toArray();
    }

    @NotNull
    @Override
    public <T1> T1[] toArray(@NotNull T1[] a) {
        return singleton.list().toArray(a);
    }

    @Override
    public boolean add(T t) {
        return singleton.list().add(t);
    }

    @Override
    public boolean remove(Object o) {
        return singleton.list().remove(o);
    }

    @Override
    public boolean containsAll(@NotNull Collection<?> c) {
        return singleton.list().containsAll(c);
    }

    @Override
    public boolean addAll(@NotNull Collection<? extends T> c) {
        return singleton.list().addAll(c);
    }

    @Override
    public boolean addAll(int index, @NotNull Collection<? extends T> c) {
        return singleton.list().addAll(index, c);
    }

    @Override
    public boolean removeAll(@NotNull Collection<?> c) {
        return singleton.list().removeAll(c);
    }

    @Override
    public boolean retainAll(@NotNull Collection<?> c) {
        return singleton.list().retainAll(c);
    }

    @Override
    public void clear() {
        singleton.list().clear();
    }

    @Override
    public T get(int index) {
        return singleton.list().get(index);
    }

    @Override
    public T set(int index, T element) {
        return singleton.list().set(index, element);
    }

    @Override
    public void add(int index, T element) {
        singleton.list().add(index, element);
    }

    @Override
    public T remove(int index) {
        return singleton.list().remove(index);
    }

    @Override
    public int indexOf(Object o) {
        return singleton.list().indexOf(o);
    }

    @Override
    public int lastIndexOf(Object o) {
        return singleton.list().lastIndexOf(o);
    }

    @NotNull
    @Override
    public ListIterator<T> listIterator() {
        return singleton.list().listIterator();
    }

    @NotNull
    @Override
    public ListIterator<T> listIterator(int index) {
        return singleton.list().listIterator(index);
    }

    @NotNull
    @Override
    public List<T> subList(int fromIndex, int toIndex) {
        return singleton.list().subList(fromIndex, toIndex);
    }

    @FunctionalInterface
    public interface ListInitializer<T> {
        List<T> initialize();
    }

    private class ListInitializerSingleton<T> {

        private final ListInitializer<T> initializer;

        private List<T> list;

        ListInitializerSingleton(ListInitializer<T> initializer) {
            this.initializer = initializer;
        }

        List<T> list() {
            if (list == null) {
                list = initializer.initialize();
            }
            return list;
        }
    }
}
public类LazyList实现列表{
私人最终列表初始值设定值单例单例;
公共懒散列表(列表初始值设定项初始值设定项){
this.singleton=新列表初始值设定项singleton(初始值设定项);
}
@凌驾
公共整数大小(){
返回singleton.list().size();
}
@凌驾
公共布尔值为空(){
返回singleton.list().isEmpty();
}
@凌驾
公共布尔包含(对象o){
返回singleton.list().contains(o);
}
@NotNull
@凌驾
公共迭代器迭代器(){
返回singleton.list().iterator();
}
@NotNull
@凌驾
公共对象[]toArray(){
返回singleton.list().toArray();
}
@NotNull
@凌驾
公共T1[]阵列(@NotNull T1[]a){
将singleton.list()返回数组(a);
}
@凌驾
公共布尔加法(T){
返回singleton.list().add(t);
}
@凌驾
公共布尔删除(对象o){
返回singleton.list().remove(o);
}
@凌驾
公共布尔containsAll(@NotNull集合c){
返回singleton.list().containsAll(c);
}
@凌驾
公共布尔addAll(@NotNull集合c){
返回singleton.list().removeAll(c);
}
@凌驾
公共布尔保留(@NotNull集合c){
返回singleton.list().retainal(c);
}
@凌驾
公共空间清除(){
singleton.list().clear();
}
@凌驾
公共T获取(整数索引){
返回singleton.list().get(索引);
}
@凌驾
公共T集(整数索引,T元素){
返回singleton.list().set(索引,元素);
}
@凌驾
公共空添加(整数索引,T元素){
singleton.list().add(索引,元素);
}
@凌驾
公共T删除(整型索引){
返回singleton.list().remove(索引);
}
@凌驾
public int indexOf(对象o){
返回singleton.list().indexOf(o);
}
@凌驾
公共int lastIndexOf(对象o){
返回singleton.list().lastIndexOf(o);
}
@NotNull
@凌驾
公共ListIterator ListIterator(){
返回singleton.list().listIterator();
}
@NotNull
@凌驾
公共ListIterator ListIterator(int索引){
返回singleton.list().listIterator(索引);
}
@NotNull
@凌驾
公共列表子列表(int fromIndex、int toIndex){
返回singleton.list()子列表(从索引到索引);
}
@功能接口
公共接口列表初始值设定项{
列表初始化();
}
私有类ListInitializerSingleton{
私有最终列表初始值设定项;
私人名单;
ListInitializerSingleton(ListInitializer初始值设定项){
this.initializer=初始值设定项;
}
列表(){
if(list==null){
list=初始值设定项.initialize();
}
退货清单;
}
}
}
用法:

DeckModel convert(Deck deck) {
    DeckModel model = new DeckModel();
    model.setName(deck.getName());
    LazyList<CardModel> cards = new LazyList<>(() -> {
        deck.getCards().stream()
                .map(card -> convert(card))
                .collect(Collectors.toList());
    })
    model.setCards(cards);
    return model;
}

CardModel convert(Card card) {
    CardModel model = new CardModel();
    model.setName(card.getName());
    LazyList<DeckModel> decks = new LazyList<>(() -> {
        card.getDecks().stream()
                .map(deck -> convert(deck))
                .collect(Collectors.toList());
    })
    model.setDecks(deks);
    return model;
}
甲板模型转换(甲板){
DeckModel模型=新DeckModel();
model.setName(deck.getName());
懒散列表卡=新懒散列表(()->{
deck.getCards().stream()
.map(卡片->转换(卡片))
.collect(Collectors.toList());
})
模型。设置卡(卡);
收益模型;
}
卡片模型转换(卡片){
CardModel model=新的CardModel();
model.setName(card.getName());
懒汉名单=新懒汉名单(()->{
card.getDecks().stream()
.map(牌组->转换(牌组))
.collect(Collectors.toList());
})
模型组(deks);
收益模型;
}

如果在将数据复制到模型对象时不需要集合,则不要调用
deck.getdeck()
。只是让模型对象有空列表,不是吗?问题是我以后可能需要在我的应用程序中使用集合,但是因为我不确定是否需要,所以我现在不想获取它。在复制时获取集合是否有问题?有那么大吗?通常您无需考虑。使用此解决方案,如果在我以后无法在应用程序中初始化DEK之前,DEK尚未初始化。@b1zzu我是否感觉您正在查看模式(反模式)中查找打开的会话?属于
public class LazyList<T> implements List<T> {

    private final ListInitializerSingleton<T> singleton;

    public LazyList(ListInitializer<T> initializer) {
        this.singleton = new ListInitializerSingleton<>(initializer);
    }

    @Override
    public int size() {
        return singleton.list().size();
    }

    @Override
    public boolean isEmpty() {
        return singleton.list().isEmpty();
    }

    @Override
    public boolean contains(Object o) {
        return singleton.list().contains(o);
    }

    @NotNull
    @Override
    public Iterator<T> iterator() {
        return singleton.list().iterator();
    }

    @NotNull
    @Override
    public Object[] toArray() {
        return singleton.list().toArray();
    }

    @NotNull
    @Override
    public <T1> T1[] toArray(@NotNull T1[] a) {
        return singleton.list().toArray(a);
    }

    @Override
    public boolean add(T t) {
        return singleton.list().add(t);
    }

    @Override
    public boolean remove(Object o) {
        return singleton.list().remove(o);
    }

    @Override
    public boolean containsAll(@NotNull Collection<?> c) {
        return singleton.list().containsAll(c);
    }

    @Override
    public boolean addAll(@NotNull Collection<? extends T> c) {
        return singleton.list().addAll(c);
    }

    @Override
    public boolean addAll(int index, @NotNull Collection<? extends T> c) {
        return singleton.list().addAll(index, c);
    }

    @Override
    public boolean removeAll(@NotNull Collection<?> c) {
        return singleton.list().removeAll(c);
    }

    @Override
    public boolean retainAll(@NotNull Collection<?> c) {
        return singleton.list().retainAll(c);
    }

    @Override
    public void clear() {
        singleton.list().clear();
    }

    @Override
    public T get(int index) {
        return singleton.list().get(index);
    }

    @Override
    public T set(int index, T element) {
        return singleton.list().set(index, element);
    }

    @Override
    public void add(int index, T element) {
        singleton.list().add(index, element);
    }

    @Override
    public T remove(int index) {
        return singleton.list().remove(index);
    }

    @Override
    public int indexOf(Object o) {
        return singleton.list().indexOf(o);
    }

    @Override
    public int lastIndexOf(Object o) {
        return singleton.list().lastIndexOf(o);
    }

    @NotNull
    @Override
    public ListIterator<T> listIterator() {
        return singleton.list().listIterator();
    }

    @NotNull
    @Override
    public ListIterator<T> listIterator(int index) {
        return singleton.list().listIterator(index);
    }

    @NotNull
    @Override
    public List<T> subList(int fromIndex, int toIndex) {
        return singleton.list().subList(fromIndex, toIndex);
    }

    @FunctionalInterface
    public interface ListInitializer<T> {
        List<T> initialize();
    }

    private class ListInitializerSingleton<T> {

        private final ListInitializer<T> initializer;

        private List<T> list;

        ListInitializerSingleton(ListInitializer<T> initializer) {
            this.initializer = initializer;
        }

        List<T> list() {
            if (list == null) {
                list = initializer.initialize();
            }
            return list;
        }
    }
}
DeckModel convert(Deck deck) {
    DeckModel model = new DeckModel();
    model.setName(deck.getName());
    LazyList<CardModel> cards = new LazyList<>(() -> {
        deck.getCards().stream()
                .map(card -> convert(card))
                .collect(Collectors.toList());
    })
    model.setCards(cards);
    return model;
}

CardModel convert(Card card) {
    CardModel model = new CardModel();
    model.setName(card.getName());
    LazyList<DeckModel> decks = new LazyList<>(() -> {
        card.getDecks().stream()
                .map(deck -> convert(deck))
                .collect(Collectors.toList());
    })
    model.setDecks(deks);
    return model;
}