休眠多对多映射不从服务层插入连接表的行

时间:2015-06-22 10:10:37

标签: hibernate many-to-many postgresql-9.1 jointable hibernate-4.x

我在hibernate中见证了奇怪的行为,我有很多关系,我有如下所示的表格

Attribute -- Attribute_Category -- Category

当我尝试运行DAO层测试时,hibernate在所有三个表中插入行,包括连接表ATTRIBUTE_CATEGORY。

@Test
@Rollback(false)
public void testAddAttribute(){
    try {
        AttributeDO attributeDO = getAttributeDO();
        List<AttributeDO> attributeDOs = new ArrayList<AttributeDO>();
        CategoryDO categoryDO = getAttributeDO().getCategoryDOs().get(0);
        attributeDOs.add(attributeDO);
        categoryDO.setAttributeDOs(attributeDOs);
        attributeDAOImpl.addAttribute(attributeDO);
        System.out.println("attribute id - " + attributeDO.getAttributeId());
    } catch (DataException cExp) {
        cExp.printStackTrace();
        Assert.fail();
    }
}

但是当我尝试在服务层中做同样的事情时,只有映射表被插入而不是连接表。

我的服务实施代码

@Override
@Transactional(propagation = Propagation.REQUIRED)
public void addAttribute(AttributeBO attributeBO) throws CrafartServiceException {
    AttributeDO attributeDO = mapper.mapAttributeBOToDO(attributeBO, new AttributeDO());
    CategoryDO categoryDO = mapper.mapCategoryBOToDO(attributeBO.getCategoryBO(), new CategoryDO(), new SeoDO());
    List<CategoryDO> categoryDOs = new ArrayList<>();
    categoryDOs.add(categoryDO);
    attributeDO.setCategoryDOs(categoryDOs);
    // creating bi directional relation ship between attribute --> category table. (category --> attribute cause unidirectional relation)
    List<AttributeDO> attributeDOs = new ArrayList<>();
    attributeDOs.add(attributeDO);
    categoryDO.setAttributeDOs(attributeDOs);
    try {
        attributeDAOImpl.addAttribute(attributeDO);
        attributeBO.setAttributeId(attributeDO.getAttributeId());
    } catch (DataException cExp) {
        throw new ServiceException("Service error - error while adding attribute", cExp);
    }
}

我没有看到dao测试和服务实现之间的区别,所有我映射bo来做对象,我做标识符合并如下所示

@Entity
@Table(name = "ATTRIBUTE")
public class AttributeDO implements Cloneable, Serializable {

/**
 * serial id
 */
private static final long serialVersionUID = -8629832877426207073L;


@Id
@Column(name = "attribute_id")
@SequenceGenerator(name = "seq_attribute", sequenceName = "seq_attribute", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_attribute")
private long attributeId;


@ManyToMany(mappedBy = "attributeDOs", cascade=CascadeType.MERGE)
private List<CategoryDO> categoryDOs;

我的类别实体

@Entity
@Table(name = "CATEGORY")
public class CategoryDO implements Serializable, Cloneable {
/**
 * 
 */
private static final long serialVersionUID = -870423497459160593L;

@Id
@Column(name = "category_id")
@SequenceGenerator(name = "seq_category", sequenceName = "seq_category", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_category")
private long categoryId;

@ManyToMany(cascade = { CascadeType.ALL })
@JoinTable(name = "ATTRIBUTE_CATEGORY", joinColumns = { @JoinColumn(name = "SUB_CATEGORY_ID") }, inverseJoinColumns = { @JoinColumn(name = "ATTRIBUTE_ID") })
private List<AttributeDO> attributeDOs;

需要帮助来解决这个奇怪的问题

1 个答案:

答案 0 :(得分:-1)

1。道我正在使用相同的对象进行保存/合并操作,在服务层,我必须映射bo来做对象,现在根据hibernate规则,没有两个对象将具有相同的标识符,但在我的case bo和do对象将具有相同的标识符,所以如果它们具有相同的标识符(类别),我必须做合并对象,之后我必须保存我新添加的属性对象。

2另一种方法,获取该标识符的对象

  

CategoryDO object = session.get(CateogryDO.class,   categoryDO.getCategoryId);

并且因为我们使用相同的对象而执行saveorupdate,这里不需要合并操作,这比前一个更有意义