如何在列表中添加产品而不加载所有数据库?

Jul*_*lin 5 database many-to-many hibernate lazy-loading

在我的域模型中,我在ProductList实体和Product实体之间有一个双向关联,具有以下hibernate映射:

@Entity @Indexed
@Table(name="product_list")
public class ProductList {

@ManyToMany(fetch=FetchType.LAZY)
@JoinTable(name = "list_items",
        inverseJoinColumns = { @JoinColumn(name = "product_id")},
        joinColumns = { @JoinColumn(name = "list_id")})
@IndexColumn(name = "item_index", base = 1, nullable = false )
@LazyCollection(LazyCollectionOption.EXTRA)
@BatchSize(size=50)
private List<Product> products = new LinkedList<Product>();
....

}

@Entity
@Table(name="logical_item")
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
public class Product {

@ManyToMany(fetch=FetchType.LAZY, mappedBy="products")
private Set<ProductList> productLists = new LinkedHashSet<ProductList>();

...
}
Run Code Online (Sandbox Code Playgroud)

但是当我尝试将产品添加到持久性产品列表时,Hibernate尝试在列表中加载所有产品!我在列表中有超过14000种产品!

Product item = (Product) session.get(Product.class, 123);
ProductList myFavoriteItems = (ProductList) session.get(ProductList.class, 321);

// Evil lazy loading (need more 512Mo of memory )
myFavoriteItems.addItem(Product item);

public void addItem(Product item){
    this.getProducts().add(item);
    item.getProductLists().add(this);
}
Run Code Online (Sandbox Code Playgroud)

如何在列表中添加产品而不加载所有数据库?

Thi*_*rry 3

我想这是当您需要更新连接表时使用多对多关系的缺点之一。

我建议从连接表中创建一个实体,然后您只需创建连接实体并保存它:

public class ProductListItem {
    @ManyToOne(...)
    private Product product;

    @ManyToOne(...)
    private ProductList productList;

    ...
}
Run Code Online (Sandbox Code Playgroud)

并且您仍然可以拥有一个瞬态 getter,而不是从产品返回产品列表:

public class Product {

    @OneToMany(...)
    private Set<ProductListItem> items;

    @Transient
    public Set<ProductList> getProductLists() {
        Set<ProductList> list = new LinkedHashSet<ProductList>();
        for(ProductListItem item : items) {
            list.add(item.getProductList());
        }
        return Collections.unmodifiableSet(list);
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

对于多对多关系的另一面也是如此。

然后,您的保存操作只需创建一个 ProductListItem 并保存它,这不会加载任何内容,并且只需要一次插入。

请小心您已经存在的 hql 查询:如果它们使用链接 Product<->ProductList,它们将不再工作。

如果您希望保留ManyToMany关系,您应该查看:http://josephmarques.wordpress.com/2010/02/22/many-to-many-revisited/(我从未尝试过此解决方案)