Hibernate5更新只收集多对多的关系

时间:2017-04-20 14:55:14

标签: java hibernate jpa orm jpa-2.0

我有以下用Hibernate 5.2映射的图表

Diagram Database

这些是我的实体类:

库存

#!/bin/bash
 echo " Please enter 1 or 2 "
read num1
while IFS= read -r line
 do
Temp1=`./fahr_kel $num1    $line`
echo  "      " $Temp1
echo "--------       -------- "
done < "project3.data"

分类

@Entity
@Table(name = "stock", catalog = "mkyongdb", uniqueConstraints = {
        @UniqueConstraint(columnNames = "STOCK_NAME"),
        @UniqueConstraint(columnNames = "STOCK_CODE") })
public class Stock implements java.io.Serializable {

    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "STOCK_ID", unique = true, nullable = false)
    private Integer stockId;

    @Column(name = "STOCK_CODE", unique = true, nullable = false, length = 10)
    private String stockCode;

    @Column(name = "STOCK_NAME", unique = true, nullable = false, length = 20)
    private String stockName;

    @ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.MERGE, CascadeType.REFRESH})
    @JoinTable(name = "stock_category", catalog = "mkyongdb", joinColumns = {
            @JoinColumn(name = "STOCK_ID", nullable = false, updatable = false) },
            inverseJoinColumns = { @JoinColumn(name = "CATEGORY_ID",
                    nullable = false, updatable = false) })
    private Set<Category> categories = new HashSet<>();

    //Getter and Setter

}

一切都运作良好。

我需要做的只是在库存中添加类别清单。我不想修改@Entity @Table(name = "category", catalog = "mkyongdb") public class Category implements java.io.Serializable { @Id @GeneratedValue(strategy = IDENTITY) @Column(name = "CATEGORY_ID", unique = true, nullable = false) private Integer categoryId; @Column(name = "NAME", nullable = false, length = 10) private String name; @Column(name = "[DESC]", nullable = false) private String desc; @ManyToMany(fetch = FetchType.LAZY, mappedBy = "categories", cascade = {CascadeType.MERGE, CascadeType.REFRESH}) private Set<Stock> stocks = new HashSet<>(); //Getter and Setter } 实体,只需在Stock表中添加或删除类别。

这是我的服务:

stock_category

这是服务的测试

@Override
@Transactional(rollbackFor = StockException.class)
public void addCategoriesToStock(Set<Category> categories, Stock stock) throws StockException{
    stock = sessionFactory.getCurrentSession().get(Stock.class, stock.getCodStock());
    stock.setCategories(categories);
    sessionFactory.getCurrentSession().update(stock);
    sessionFactory.getCurrentSession().flush();
}

测试运行良好且没有错误,但在浏览与类别“13”(@Test public void testAddCategoriesStock() throws Exception { Stock newValues = new Stock(); newValues.setStockId(1); Category category = new Category(); category.setCategoryId(13); dao.addCategoriesToStock(new HashSet<>(Arrays.asList(category)), newValues); List<Stock> stocks = dao.getAllStockeByCategoriesCriteria(category); for (Stock stock : stocks) { System.out.println(stock); } } )相关联的库存时,它不会带给我任何库存。然后先前执行的操作不起作用。

如何添加或删除类别?

2 个答案:

答案 0 :(得分:1)

您必须在两边添加依赖项,因此您缺少将Stock添加到categories

@Override
@Transactional(rollbackFor = StockException.class)
public void addCategoriesToStock(List<Category> categories, Stock stock) throws StockException{
    stock = sessionFactory.getCurrentSession().get(Stock.class, stock.getCodStock());
    stock.setCategories(categories);

    for(Category cat: categories){
        cat.getStocks().add(stock);
    }

    sessionFactory.getCurrentSession().merge(stock);
    sessionFactory.getCurrentSession().flush();
}

此外,我认为您应该使用merge代替update来使级联工作。

之后,您的代码应保存关系。

答案 1 :(得分:0)

根据第一个响应,这是我在方法中留下的代码。

更改签名,因为我只需要实体的标识符就可以将它们联系起来,并且如表明Maciej Kowalski关系必须保持两种方式

我还通过Set更改了列表,以确保值不会重复

这是我的服务,为关系添加类别列表

@Override
@Transactional(rollbackFor = StockException.class)
public void addCategoriesToStock(Set<Integer> categoryCodes, Integer codStock) throws StockException{
    //I get the stock I'm going to associate
    Stock stock = sessionFactory.getCurrentSession().get(Stock.class, codStock);
    if (categoryCodes != null) {
    //For each category to add to the stock, I consult and add the relationship in both entities
        for (Integer codCategory : categoryCodes) {
            Category category = sessionFactory.getCurrentSession().get(Category.class, codCategory);
            category.add(stock);
            stock.add(category);
        }
    }
    sessionFactory.getCurrentSession().merge(stock);
    sessionFactory.getCurrentSession().flush();
}

这将是从关系中删除类别列表的服务

@Override
@Transactional(rollbackFor = StockException.class)
public void removeCategoriesToStock(Set<Integer> categoryCodes, Integer codStock) throws StockException{
    //I get the stock that I will disassociate
    Stock stock = sessionFactory.getCurrentSession().get(Stock.class, codStock);
    if (categoryCodes != null) {
    //For each category to eliminate the stock, I consult and eliminate the relationship in both entities
        for (Integer codCategory : categoryCodes) {
            Category category = sessionFactory.getCurrentSession().get(Category.class, codCategory);
            category.remove(stock);
            stock.remove(category);
        }
    }
    sessionFactory.getCurrentSession().merge(stock);
    sessionFactory.getCurrentSession().flush();
}

我怀疑的是,在我能够在两个实体之间建立关系之前,我必须在数据库中查询它们以获取对象并对其进行操作。因为我必须为我将关联的每个标识符执行此操作,我认为应该存在性能问题。

但是目前我会留下它,以防我找到更优化的方式,这样发布在这里