数据库为:Oracle 9i主表为: 用户表(member)
    create table member (
        member_id number(10,0) not null,
        name varchar2(10 char),
        sex varchar2(1 char),
        primary key (member_id)
    )从表为: 订单表(orders)
    create table orders (
        Order_id number(10,0) not null,
        total_price float,
        member_id number(10,0),
        primary key (Order_id)
    )
    alter table orders 
        add constraint FKC3DF62E5CDAA53AA 
        foreign key (member_id) 
        references member双向关联映射细分:在主表member的关系映射文件中:
1)一端(member)中对多端(order)采取了延迟加载策略:lazy="true"默认
2)将多端(order)的传播持久性(级联)设置为最全面的全部级联(包括孤儿模式):cascade="all-delete-orphan"
3)将维护关系的控制权交给多端(order):inverse="true"在从表orders的关系映射文件中:
1)多端(order)对一端(member)采取了预先抓取策略:fetch="join"(并且要把一端‘member’映射文件的class标签的lazy属性设置为false)
2)将一端(member)的传播持久性(级联)设置为存储、更新:cascade="save-update"用户表member(主表):
<hibernate-mapping>
<class name="hbp.ch04.ex03.model.Member" table="member" lazy="false">
<id name="memberId" column="member_id" type="java.lang.Integer">
<generator class="native"></generator>
</id>
<property name="name" column="name" type="java.lang.String" length="10"></property>
<property name="sex" column="sex" type="java.lang.String" length="1"></property>
<set name="orders" order-by="order_id"  inverse="true" lazy="true" cascade="all-delete-orphan">
<key column="member_id"></key>
<one-to-many class="hbp.ch04.ex03.model.Order"/>
</set>
</class>
</hibernate-mapping>订单表orders(从表)
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- 
    Mapping file autogenerated by MyEclipse - Hibernate Tools
-->
<hibernate-mapping>
<class name="hbp.ch04.ex03.model.Order" table="orders">
<id name="orderId" column="Order_id" type="java.lang.Integer">
<generator class="native"></generator>
</id>
<property name="totalPrice" column="total_price" type="java.lang.Float"></property>
<many-to-one name="member" column="member_id" class="hbp.ch04.ex03.model.Member" cascade="save-update"  fetch="join"></many-to-one>
</class>
</hibernate-mapping>pojo类:Member------------------------import java.util.HashSet;
import java.util.Set;public class Member {

// Fields

private Integer memberId;
private String name;
private String sex;
private Set orders;        // Constructors
        /** default constructor */ public Member() {
// TODO Auto-generated constructor stub
}        // Property accessors /**
 * @return the orders
 */
public Set getOrders() {
if (orders == null) {
orders = new HashSet();
}
return orders;
}
        // 其他 get/set访问方法省略。。
}Order-----------------
public class Order { // Fields
}Member的DAO类(DAO实现的接口省略)import org.hibernate.*;
import util.HibernateSessionFactory;import hbp.dao.MemberDAO;
import hbp.model.Member;
import hbp.model.Order;public class HibernateMemberDAO implements MemberDAO { public void deleteMember(Integer memberId) {
// TODO Auto-generated method stub
Session session = HibernateSessionFactory.getSession();
session.beginTransaction();

Member member = (Member)session.get(Member.class, memberId);
session.delete(member);
session.getTransaction().commit();
session.close();

} public Member getMemberById(Integer memberId) {
// TODO Auto-generated method stub
Session session = HibernateSessionFactory.getSession();
session.beginTransaction();

Member member = (Member)session.get(Member.class, memberId);
//Hibernate.initialize(member.getOrders());

session.getTransaction().commit();
return member;
} public Order getOrderById(Integer orderId) {
// TODO Auto-generated method stub
Session session = HibernateSessionFactory.getSession();
session.beginTransaction();

Order order=(Order)session.get(Order.class, orderId);
//Hibernate.initialize(order.getMember());
session.getTransaction().commit();
return order;
} public void saveMember(Member member) {
// TODO Auto-generated method stub
Session session = HibernateSessionFactory.getSession();
session.beginTransaction();

session.save(member);

session.getTransaction().commit(); } public void saveOrder(Integer memberId, Order order) {
// TODO Auto-generated method stub
Session session = HibernateSessionFactory.getSession();
session.beginTransaction();

Member member = (Member)session.get(Member.class, memberId);
order.setMember(member);
member.getOrders().add(order);

session.save(member);

session.getTransaction().commit();
}

public void delete_orphan(Member member,Order order) {
Session session = HibernateSessionFactory.getSession();
session.beginTransaction();

member.getOrders().remove(order);

session.save(member);

session.getTransaction().commit();

}
}
测试方法:
import java.util.HashSet;import hbp.dao.hibernate.HibernateMemberDAO;
import hbp.model.Member;
import hbp.model.Order;
import junit.framework.TestCase;public class HibernateMemberDAO03Test extends TestCase {

public void testSaveMember(){
HibernateMemberDAO memberDAO = new HibernateMemberDAO();

Member member, member2, member3; 
member = new Member();
member.setName("李四");
member.setSex("f");
member.setOrders(new HashSet());
memberDAO.saveMember(member);

member2 = new Member();
member2.setName("王五");
member2.setSex("m");
member2.setOrders(new HashSet());
memberDAO.saveMember(member2);

member3 = new Member();
member3.setName("张三");
member3.setSex("m");
member3.setOrders(new HashSet());
memberDAO.saveMember(member3);
}

public void testSaveOrder() {
HibernateMemberDAO memberDAO = new HibernateMemberDAO();
Order order = new Order();
order.setTotalPrice(new Float(12.34));
memberDAO.saveOrder(new Integer(3), order);

}

public void testGetMemberById() {
HibernateMemberDAO memberDAO = new HibernateMemberDAO();
Member member = memberDAO.getMemberById(new Integer(3));
System.out.println("会员姓名:" + member.getName());
System.out.println("订单数量:" + member.getOrders().size());
}

public void testGetOrderById() {
HibernateMemberDAO memberDAO = new HibernateMemberDAO();
Order order = memberDAO.getOrderById(new Integer(4));
System.out.println("会员姓名:" + order.getMember().getName());
System.out.println("订单价格:" + order.getTotalPrice());
}




public void testDeleteMember() {
/*
HibernateMemberDAO memberDAO = new HibernateMemberDAO();
memberDAO.deleteMember(new Integer(2));
memberDAO.deleteMember(new Integer(3));
*/

HibernateMemberDAO memberDAO = new HibernateMemberDAO();
Member member = memberDAO.getMemberById(new Integer(3));
Order order = memberDAO.getOrderById(new Integer(4));
memberDAO.delete_orphan(member, order);

}

}由于帖子字数有限,其余内连在第一个回复中!!!
往下看

解决方案 »

  1.   


    连接楼上未完内容...
    问题是:
    一般先注册几个会员,当注册时还不会有订单(这时还用不到级联存储订单的功能),这是单方存储member;
    当主表member的映射文件的set标签中的 cascade="all"的时候,测试所有的方法执行是没有问题的。而当把主表member的映射文件的set标签中的cascade="all-delete-orphan"时,
    在第一个测试方法(testSaveMember)中就出了问题,
    testSaveMember方法介绍:一般先注册几个会员,当注册时还不会有订单(这时还用不到级联存储订单的功能),这是单方存储member;
    public void testSaveMember(){
    HibernateMemberDAO memberDAO = new HibernateMemberDAO();

    Member member, member2, member3; 
    member = new Member();
    member.setName("李四");
    member.setSex("f");
    member.setOrders(new HashSet());
    memberDAO.saveMember(member);

    member2 = new Member();
    member2.setName("王五");
    member2.setSex("m");
    member2.setOrders(new HashSet());
    memberDAO.saveMember(member2);

    member3 = new Member();
    member3.setName("张三");
    member3.setSex("m");
    member3.setOrders(new HashSet());
    memberDAO.saveMember(member3);
    }程序运行到第一个测试方法testSaveMember()时member存进去了,当存储member2(memberDAO.saveMember(member2);)的时候,
    调用了MemberDAO的
    public void saveMember(Member member) {
    // TODO Auto-generated method stub
    Session session = HibernateSessionFactory.getSession();
    session.beginTransaction();

    session.save(member);

    session.getTransaction().commit(); }在session.getTransaction().commit();这句就出现了如下异常:org.hibernate.HibernateException: A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: hbp.ch04.ex03.model.Member.orders
    at org.hibernate.engine.Collections.processDereferencedCollection(Collections.java:96)
    at org.hibernate.engine.Collections.processUnreachableCollection(Collections.java:39)
    at org.hibernate.event.def.AbstractFlushingEventListener.flushCollections(AbstractFlushingEventListener.java:218)
    at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:77)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
    at hbp.ch04.ex03.dao.hibernate.HibernateMemberDAO.saveMember(HibernateMemberDAO.java:54)
    at hbp.ch04.ex03.dao.hibernate.test.HibernateMemberDAO03Test.testSaveMember(HibernateMemberDAO03Test.java:26)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at junit.framework.TestCase.runTest(TestCase.java:154)
    at junit.framework.TestCase.runBare(TestCase.java:127)
    at junit.framework.TestResult$1.protect(TestResult.java:106)
    at junit.framework.TestResult.runProtected(TestResult.java:124)
    at junit.framework.TestResult.run(TestResult.java:109)
    at junit.framework.TestCase.run(TestCase.java:118)
    at junit.framework.TestSuite.runTest(TestSuite.java:208)
    at junit.framework.TestSuite.run(TestSuite.java:203)
    at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
    Hibernate及数据库的运行情况:
    17:49:29,171 DEBUG SchemaExport:303 - 
        drop table member cascade constraints
    17:49:29,312 DEBUG SchemaExport:303 - 
        drop table orders cascade constraints
    17:49:29,328 DEBUG SchemaExport:303 - 
        drop sequence hibernate_sequence
    17:49:29,328 DEBUG SchemaExport:303 - 
        create table member (
            member_id number(10,0) not null,
            name varchar2(10 char),
            sex varchar2(1 char),
            primary key (member_id)
        )
    17:49:29,359 DEBUG SchemaExport:303 - 
        create table orders (
            Order_id number(10,0) not null,
            total_price float,
            member_id number(10,0),
            primary key (Order_id)
        )
    17:49:29,375 DEBUG SchemaExport:303 - 
        alter table orders 
            add constraint FKC3DF62E5CDAA53AA 
            foreign key (member_id) 
            references member
    17:49:29,390 DEBUG SchemaExport:303 - 
        create sequence hibernate_sequence
    17:49:29,390  INFO SchemaExport:196 - schema export complete
    Hibernate: 
        select
            hibernate_sequence.nextval 
        from
            dual
    Hibernate: 
        /* insert hbp.ch04.ex03.model.Member
            */ insert 
            into
                member
                (name, sex, member_id) 
            values
                (?, ?, ?)
    Hibernate: 
        select
            hibernate_sequence.nextval 
        from
            dual
    Hibernate: 
        /* load hbp.ch04.ex03.model.Member */ select
            member0_.member_id as member1_0_0_,
            member0_.name as name0_0_,
            member0_.sex as sex0_0_ 
        from
            member member0_ 
        where
            member0_.member_id=?
    Hibernate: 
        /* load hbp.ch04.ex03.model.Member */ select
            member0_.member_id as member1_0_0_,
            member0_.name as name0_0_,
            member0_.sex as sex0_0_ 
        from
            member member0_ 
        where
            member0_.member_id=?
    Hibernate: 
        /* load hbp.ch04.ex03.model.Order */ select
            order0_.Order_id as Order1_1_1_,
            order0_.total_price as total2_1_1_,
            order0_.member_id as member3_1_1_,
            member1_.member_id as member1_0_0_,
            member1_.name as name0_0_,
            member1_.sex as sex0_0_ 
        from
            orders order0_ 
        left outer join
            member member1_ 
                on order0_.member_id=member1_.member_id 
        where
            order0_.Order_id=?
    Hibernate: 
        /* load hbp.ch04.ex03.model.Member */ select
            member0_.member_id as member1_0_0_,
            member0_.name as name0_0_,
            member0_.sex as sex0_0_ 
        from
            member member0_ 
        where
            member0_.member_id=?
    数据库中只有member表里存入了第一个member(李四)的数据。
    为什么在主表(member)的映射文件中设置多端(order)的级联为<set ... cascade="all"> 存储的时候就没事,
    而设置成<set ... cascade="all-delete-orphan">时就出现了错误呢?
      

  2.   

    帖子中Order类没有写全类中的域(成员变量)和构造器
    补上Order类的POJO:public class Order { // Fields

    private Integer orderId;
    private Member member;
    private Float totalPrice;

    // Constructors

    /** default constructor */
    public Order() {
    // TODO Auto-generated constructor stub
    }

    // Property accessors
            // 其他 get/set访问方法省略。。
    }