导航

Hibernate映射(一)--------set

Posted on 2013-03-21 23:37  tnjin  阅读(193)  评论(0)    收藏  举报
 

hibernate的强大就不多说,通过配置文件可以实现查询结果集的自动封装也不多说,我就直接从集合映射中来说吧。

常用的映射集合以Set和List最为常见,先以set为例。

假定有Order(订单)以及Item(订单项)两个JavaBean。订单中可以包含多个Item,于是在Order的POJO映射文件即Order.hbm.xml文件中应该:

<set name="items">
        <!-- key表示用于维护关系的列为order_id -->
        <key column="order_id"></key>
        <!-- 这里表示Set中的元素为Item -->
        <one-to-many class="entity.Item"/>
        </set>

Order中有属性:

private Set<Item> items;//这里只能使用Set接口,而不能使用Set的实现类

至于为什么一定要用Set接口就不知道了,但是,实例化时是可以使用HashSet这样的实现类的。

这样,在编写的测试用例中写如下代码:

public static void main(String []args){
        Session s=HibernateSessionFactory.getSession();
    Transaction tx=    s.beginTransaction();
    tx.begin();
    Order order=(Order)s.get(Order.class, 1);
    System.out.println(order.getAddress());
    System.out.println(order.getItems());
    tx.commit();
    s.close();
    }

是可以看出控制台输出我们想要的东西的。

 

但是如果需要保存一份新的Order呢?

@Test
    public void test_save(){
        Order order=new Order();
        order.setAddress("北京市朝阳区");
        order.setUserId(2);
Item it=new Item();
        
        it.setOrderId(order.getId());
        it.setProductId(3);
        Set<Item> items=new HashSet<Item>();
        items.add(it);
        order.setItems(items);
        Session s=HibernateSessionFactory.getSession();
        Transaction tx=    s.beginTransaction();
        tx.begin();
        s.save(order);
        tx.commit();
        
        s.close();
    }

会有异常抛出:

Could not synchronize database state with session
org.hibernate.TransientObjectException

因为这时候,hibernate对于Set集合使用的是update语句,而非insert语句

Hibernate: 
    insert 
    into
        test.d_order
        (user_id, address) 
    values
        (?, ?)
Hibernate: 
    update
        test.d_item 
    set
        order_id=? 
    where
        id=?

其实只需在Order.hbm.xml中配置Set的cascade属性为all即可,也可以选择其他的save-update也可以。

此时save操作是正常的,Hibernate执行的SQL语句为:

Hibernate: 
    insert 
    into
        test.d_order
        (user_id, address) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        test.d_item
        (order_id, product_id) 
    values
        (?, ?)
Hibernate: 
    update
        test.d_item 
    set
        order_id=? 
    where
        id=?

为什么还会执行一次update?现在还不明白

——————————————————————————————————————————————————————————————————

关于cascade属性的可能值有
    all: 所有情况下均进行关联操作,即save-update和delete。
    none: 所有情况下均不进行关联操作。这是默认值。
    save-update: 在执行save/update/saveOrUpdate时进行关联操作。
    delete: 在执行delete 时进行关联操作,但不具备级联保存和更新。
    all-delete-orphan: 当一个节点在对象图中成为孤儿节点时,删除该节点,也支持级联删除和级联保存更新。
比如在一个一对多的关系中,Student包含多个book,当在对象关系中删除一个book时,此book即成为孤儿节点,即被删除。

——————————————————————————————————————————————————————————————————
以下为此用例的数据库建表语句:

create table d_order(id int(4) 
primary key auto_increment,
user_id int(4),
address varchar(30))default charset=UTF8;
drop table d_item;

create table d_item(id int(4) primary key auto_increment,
order_id int(4),
product_id int(4));

insert into d_order(user_id,address )values(1,'中华人民共和国');
insert into d_item(order_id ,product_id) values(1,2);