Java中使用Hibernate系列之映射关联启动工作学习(第五节)

前面一节我们建好了映射文件,现在我们把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();
}

在加载一Person和Event后,使用普通的集合方法就可容易地修改我们定义的集合,Hibernate会自动检测到集合已经被修改并需要更新回数据库,这叫做自动脏检查(automatic dirty checking),你也可以尝试修改任何对象的name或者date属性,只要他们处于持久化状态,也就是被绑定到某个Hibernate 的Session上,Hibernate监视任何改变并在后台隐式写的方式执行SQL。

网络配图

同步内存状态和数据库的过程,通常只在单元操作结束的时候发生,称此过程为清理缓存(flushing),在我们的代码中,工作单元由数据库事务的提交(或者回滚)来结束——这是由CurrentSessionContext类的thread配置选项定义的。

当然,你也可以在不同的单元操作里面加载person和event,或在Session以外修改不是处在持久化(persistent)状态下的对象,还可以在一个集合被脱管时修改它:

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();
Event anEvent = (Event) session.load(Event.class, eventId);
session.getTransaction().commit();
aPerson.getEvents().add(anEvent);
Session session2 = HibernateUtil.getSessionFactory().getCurrentSession();
session2.beginTransaction();
session2.update(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);
}

我们可以自己设计一个值类型的集合,这在概念上与引用其它实体的集合有很大的不同。

好了,这一节的学习先到这里,后面章节中会继续学习Hibernate。我们学习方式是每一节学习一个知识点(每天花10分钟学习)。

原文发布于微信公众号 - Java学习网(javalearns)

原文发表时间:2017-12-01

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏陈树义

J2EE中的过滤器和拦截器

过滤器和拦截器的相似之处就是拦截请求,做一些预处理或者后处理。 而过滤器和拦截器的区别在于过滤器是相对HTTP请求而言的,而拦截器是相对Action中的方法的。...

64950
来自专栏分布式系统进阶

Cluster版本中的Meta

11640
来自专栏JackieZheng

RabbitMQ入门-Routing直连模式

Hello World模式,告诉我们如何一对一发送和接收消息; Work模式,告诉我们如何多管齐下高效的消费消息; Publish/Subscribe模式,告...

286100
来自专栏Java编程技术

使用数据库悲观锁实现不可重入的分布式锁

在同一个jvm进程中时,可以使用JUC提供的一些锁来解决多个线程竞争同一个共享资源时候的线程安全问题,但是当多个不同机器上的不同jvm进程共同竞争同一个共享资源...

7910
来自专栏LinXunFeng的专栏

iOS - ARC与MRC的单例设计模式

12830
来自专栏雨尘分享

2018 - iOS 面试题汇总一般面试题BAT面试题

4.8K30
来自专栏大内老A

Dora.Interception,为.NET Core度身打造的AOP框架 [3]:多样化拦截器应用方式

在《以约定的方式定义拦截器》中,我们通过对拦截器的介绍了Dora.Interception的两种拦截机制,即针对接口的“实例拦截”针对虚方法的“类型拦截”。我们...

10040
来自专栏JavaEdge

Java并发编程实战系列13之显式锁 (Explicit Locks)

Java5之前只能用synchronized和volatile,5后Doug Lea加入了ReentrantLock,并不是替代内置锁,而是当内置锁机制不适用时...

50170
来自专栏coder修行路

SocketServer源码学习(一)

SocketServer其实是对socket更高级的封装正如官网上说的: The socketserver module simplifies the task...

32570
来自专栏技术博客

Asp.Net Web API 2第十一课——在Web API中使用Dependency Resolver

阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.h...

11240

扫码关注云+社区

领取腾讯云代金券