数据库为: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);
}
}由于帖子字数有限,其余内连在第一个回复中!!!
往下看
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);
}
}由于帖子字数有限,其余内连在第一个回复中!!!
往下看
解决方案 »
- Myeclipse中的debug模式绑定到一个固定的之前版本的工程去了!
- Struts2日期循环累加,翻页显示下一个10天的实现问题。
- java写xml到页面
- Hibernate与Orcale关于主键自动增长的问题
- jboss部署多个工程 报内存溢出
- 为什么读取出来的text会多了3个"\n"?
- Struts问题,关于调用JavaScript对<html:text>进行限制,以控制用户输入。
- 一个Struts问题,请教高手。
- 请教一个远程调试的问题
- 为什么在数据库中用查询语句可以查询两条数据但是连接到java程序中怎么就只能输出一条呢
- 关于EJB3.0的多对多映射问题
- JAVA servlet 的一个奇怪问题
连接楼上未完内容...
问题是:
一般先注册几个会员,当注册时还不会有订单(这时还用不到级联存储订单的功能),这是单方存储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">时就出现了错误呢?
补上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访问方法省略。。
}