Hibernate学习笔记(五)
来源:互联网 发布:mac u盘刻录dmg 编辑:程序博客网 时间:2024/06/08 00:43
使关联工作
我们把一些 people 和 events 一起放到 EventManager
的新方法中:
private void addPersonToEvent(Long personId, Long eventId) {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Person aPerson = (Person) session.load(Person.class, personId);
Event anEvent = (Event) session.load(Event.class, eventId);
aPerson.getEvents().add(anEvent);
session.getTransaction().commit();
}
如你所见,没有显式的 update()
或 save()
,Hibernate 会自动检测到集合已经被修改并需要更新回数据库。这叫做自动脏检查(automatic dirty checking),你也可以尝试修改任何对象的 name 或者 date 属性,只要他们处于持久化状态,也就是被绑定到某个 Hibernate 的 Session
上(如:他们刚刚在一个单元操作被加载或者保存),Hibernate 监视任何改变并在后台隐式写的方式执行 SQL。同步内存状态和数据库的过程,通常只在单元操作结束的时候发生,称此过程为清理缓存(flushing)。在我们的代码中,工作单元由数据库事务的提交(或者回滚)来结束——这是由 CurrentSessionContext
类的 thread
配置选项定义的。
当然,你也可以在不同的单元操作里面加载 person 和 event。或在 Session
以外修改不是处在持久化(persistent)状态下的对象(如果该对象以前曾经被持久化,那么我们称这个状态为脱管(detached))。你甚至可以在一个集合被脱管时修改它:
private void addPersonToEvent(Long personId, Long eventId) {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Person aPerson = (Person) session
.createQuery("select p from Person p left join fetch p.events where p.id = :pid")
.setParameter("pid", personId)
.uniqueResult(); // Eager fetch the collection so we can use it detached
Event anEvent = (Event) session.load(Event.class, eventId);
session.getTransaction().commit();
// End of first unit of work
aPerson.getEvents().add(anEvent); // aPerson (and its collection) is detached
// Begin second unit of work
Session session2 = HibernateUtil.getSessionFactory().getCurrentSession();
session2.beginTransaction();
session2.update(aPerson); // Reattachment of aPerson
session2.getTransaction().commit();
}
对 update
的调用使一个脱管对象重新持久化,你可以说它被绑定到一个新的单元操作上,所以在脱管状态下对它所做的任何修改都会被保存到数据库里。这也包括你对这个实体对象的集合所作的任何改动(增加/删除)。
这对我们当前的情形不是很有用,但它是非常重要的概念,你可以把它融入到你自己的应用程序设计中。在EventManager
的 main 方法中添加一个新的动作,并从命令行运行它来完成我们所做的练习。如果你需要 person 及 event 的标识符 — 那就用 save()
方法返回它(你可能需要修改前面的一些方法来返回那个标识符):
else if (args[0].equals("addpersontoevent")) {
Long eventId = mgr.createAndStoreEvent("My Event", new Date());
Long personId = mgr.createAndStorePerson("Foo", "Bar");
mgr.addPersonToEvent(personId, eventId);
System.out.println("Added person " + personId + " to event " + eventId);
}
上面是个关于两个同等重要的实体类间关联的例子。像前面所提到的那样,在特定的模型中也存在其它的类和类型,这些类和类型通常是“次要的”。你已看到过其中的一些,像 int
或 String
。我们称这些类为值类型(value type),它们的实例依赖(depend)在某个特定的实体上。这些类型的实例没有它们自己的标识(identity),也不能在实体间被共享(比如,两个 person 不能引用同一个 firstname
对象,即使他们有相同的 first name)。当然,值类型并不仅仅在 JDK 中存在(事实上,在一个 Hibernate 应用程序中,所有的 JDK 类都被视为值类型),而且你也可以编写你自己的依赖类,例如Address
,MonetaryAmount
。
你也可以设计一个值类型的集合,这在概念上与引用其它实体的集合有很大的不同,但是在 Java 里面看起来几乎是一样的。
- Hibernate学习笔记(五)
- Hibernate学习笔记(五)
- hibernate学习笔记(五)
- Hibernate学习笔记五
- Hibernate学习笔记(五)----关系映射
- Hibernate学习笔记(五)(Hibernate映射类型)
- Hibernate学习笔记之五
- [学习]Hibernate 3.2 学习笔记之五
- Hibernate学习笔记(五)【映射组成关系】
- Hibernate学习笔记(五)映射组件属性
- Hibernate学习笔记(五)【映射组成关系】
- 学习笔记(五)
- 学习笔记(五)
- Spring学习笔记(五)使用Hibernate持久层 --- 2 问题与解决总结
- Spring 学习笔记(五)整合Hibernate---- 3 问题和解决 补充2
- Hibernate学习笔记(五)——多对多映射
- Hibernate学习笔记(五)--数据库事务与并发
- Hibernate学习笔记(五)--数据库事务与并发
- 一切都是最好的安排
- 使用命令安装和卸载服务
- 极限挑战—C#+ODP 100万条数据导入Oracle数据库仅用不到1秒
- IPhone短信设置
- 用C#实现的内存映射
- Hibernate学习笔记(五)
- CISCO DHCP 配置
- win32中SetCapture 和 ReleaseCapture的使用
- Android 联网监控抓包工具的制作(tcpdump的使用)
- jsp 九大内置对象
- 住房商业贷款利率、每万元需付利息
- 转载: WebView学习指南
- Hibernate学习笔记(六)
- CSDN上传相册超级不方便,所以我不喜欢用这个博客了