`
shang
  • 浏览: 193574 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

JPA规范的主要内容

    博客分类:
  • JPA
阅读更多

Entity Identity 实体标识
一般采用单一值做为entity identity
采用compsite primary key时,必须单独建立一个表示主键的类-primary key class主键类。这样在实体上compsite primary key就可以用一个属性(primary key class类型)表示
持久化框架内部很多地方使用entity identity进行处理,因此primary key class要正确实现equals、hashCode方法
另外应用层需要注意,对persistence context中受管理的对象,不要修改主键值,否则持久化框架无法承诺带来的影响,因为persistence context只能基于entity identity标识实体身份

Accessor of Persistent Fields and Properties 持久化值域和属性的访问器
Persistent state(即需要持久化的fields或properties)的存取分2种类型:field-based和property-based
field-based时持久化框架直接存取instance variables,property-based时则通过getter、setter方法存取
使用property-based时,在setter、getter方法中可能包含业务逻辑,对于应用层而言,需要注意的是持久化框架从数据库加载数据,为实体属性赋值时,各属性的赋值顺序是无法承诺的,因此getter、setter中的业务逻辑需要注意这一点
另外使用property-based时如果还将属性声明为lazy-fetching,则应用层不应当访问相应的instance variable,因为持久化框架可能对setter、getter进行注入以实现lazy-fetching,直接访问instance variable可能获取不到值
对于集合类型,JPA规定必须使用java.util下面的Collection、Set、Map、List这几个接口,关于List、Set、Map、Bag的语义,参考
这篇post  

Persistence Context 持久化上下文

   

 
Persistence Context是持久化框架需要维护的一个中间容器,其中会存放受管理对象的副本,例如从数据库获取的实体对象,或者调用持久化框架保存过的对象等
主要作用有:缓存(例如NHibernate的一级缓存概念)、支持Flush操作、辅助实现实体以及属性的Dirty检查等
JPA将persistence context分为2种类型:PersistenceContextType.TRANSACTION和 PersistenceContextType.EXTENDED。TRANSACTION类型(默认类型)的persistence context生命周期与transaction scope一致,例如事务开始时为生命周期的开始阶段,事务提交或回滚时生命周期结束。EXTENDED类型的生命周期基本与EntityManager 一致,在EntityManager创建时开始,在EntityManager关闭时结束。实现Extended类型的persistence context时需要注意其生命周期可能跨越多个事务以及不在事务范围内的情况,伴随的是这些情况下对persistence context中实例对象生命周期以及相关操作的影响,例如version控制等

Entity Instance's Life Cycle 实例对象生命周期
实例对象的生命周期可以参考一下这篇post
实例对象的生命周期有4种状态:
New: 新创建的实例对象,没有identity值
Managed: 在持久化上下文中受管理的对象 
Detached: 游离于持久化上下文之外的实例对象
Removed: 被删除的实例对象
JPA中详细定义了实例对象伴随着EntityManager的各种操作时,生命周期状态间的转换关系

JPA声明了entity instance life cycle的几个callback方法:PrePersist、PostPersist、PreRemove、PostRemove、 PreUpdate、PostUpdate、PostLoad,对其语义进行了比较详细的说明

Entity Relationships 实体关系
JPA定义了one-to-one、one-to-many、many-to-one、many-to-many 4种关系

Owning side, Inverse side 关系的所有方、反向方
在关联关系的2方之中,关系的所有者一方为owning side,另一方为inverse side。关系的所有者可以这样来理解,将所有者一方的实例删除后,这个2方关系的任何信息都彻底消失。假如逻辑上表A有一个外键,引用自表B的主键(所谓逻辑上是指数据库中并没有建立这个外键关系),如果将表B中某条数据b1删除,A、B间相应实例对象的关联关系可能并不会彻底消除,因为表A中可能还存在某数据a1引用了b1的主键值,因此与B对应的实体类就不是owning side了
因此拥有外键的一方就是owning side了,这个在one-to-one的关系中比较清晰;one-to-many、many-to-one中,many的一方为owning side;many-to-many中任何一方都可以作为owning side
Owning side、inverse side将作为cascade相关操作的依据之一

JPA详细定义了默认情况下对以下一些映射的处理方式:
双向one-to-one;双向one-to-many、many-to-one;单向single-valued(单向one-to-one、 many-to-one);双向many-to-many;单向multi-valued(单向one-to-many、many-to-many)

Inheritance 继承
Inheritance Mapping Strategies包括:
Single table per class hierarchy,使用一个discriminator column区别子类,优点是很好的支持多态关系、查询,缺点是子类独有的字段需要允许为null
Table per concrete entity class,缺点是不好支持多态关系,通常需要对各子类分别使用单独的SQL或者使用UNION语句
Joined subclass,与table per concrete entity class区别是,将公共属性的superclass使用一个表存储,这种策略也能较好的支持多态关系,缺点是需要多个JOIN关系
详细参考这篇post 

Optimistic Locking and Concurrency 乐观锁及并发控制
JPA默认应用层将使用乐观锁机制
使用乐观锁时entity必须声明一个version属性,该字段的值由持久化框架自动维护,应用层不能修改。持久化框架可以引入其它机制实现乐观锁检查,或者实现更细粒度的乐观锁控制,JPA不做要求
JPA的乐观锁机制是基于数据行的

JPA中声明了Lock Mode,可以实现悲观锁效果,至于实现方式不作具体要求,只要确保不存在P1: dirty read、P2: non-repeatable read就行
LockModeType有READ和WRITE 2种
对于WRITE模式,在isolation level为read commited情况下数据库可以确保不会出现P1、P2两种状况
READ模式一般使用数据库的锁实现,用它实现悲观锁效果

Query Language 查询语言
类SQL的语法,但是带上了较明显的对象特征
声明了SELECT、UPDATE、DELETE 3种语句

用简单的例子浏览一下大致特性
1. 使用实体间的关联关系

SELECT   DISTINCT  o
FROM   Order  o  JOIN  o.lineItems l  JOIN  l.product p
WHERE  p.productType  =   ' office_supplies '
JOIN子句不再需要ON条件部分了,因为对象之间已经定义了关联关系

2. Collection Member Declarations
SELECT   DISTINCT  o
FROM   Order  o,  IN (o.lineItems) l
WHERE  l.product.productType  =   ' office_supplies '
与1中的语句是等效的
FROM子句中为Order实体定义了别名o(Identification Variables);o.lineItems是集合类型的属性,IN(o.lineItems) l 的语义是:Order实例对象的lineItems中必须有符合后续条件的,l则代表lineItems中的每个对象;WHERE子句进一步声明了对l的过滤条件

JPA中把l.product这种表达式叫做path expression(An identification variable followed by the navigation operator (.) and a state-field or association-field is a path expression)
path express中每个点号后面的内容,有三种类型:persistent field、single-valued relationship field、collection-valued relationship field。如果是collection-valued relationship field则只能在特定的场景 下使用
例如上面1、2例子中,如果lineItems不是集合类型,则这2个例子的语句都等效于下面的写法(lineItems属性改名为lineItem以区别于集合这个概念):
3. 
SELECT   DISTINCT  o
FROM   Order  o
WHERE  o.lineItem.product.productType  =   ' office_supplies '
对path expression中的关联关系,JPA规定使用INNER JOIN操作,因此上面语句等效前面的示例1、2
但当lineItems为collection-valued relationship field时,上面写法不支持,必须采用1或2的写法
特定场景 包括上面示例出来的JOIN子句、Collection Member Declarations这2种,还有Empty Collection Comparison Expressions、Collection Member Expressions中可以使用

4. Empty collection comparison expressions
SELECT  o
FROM   Order  o
WHERE  o.lineItems  IS   [ NOT ]  EMPTY

5. Collection Member Expressions
SELECT  o
FROM   Order  o
WHERE  :lineItem MEMBER  [OF]   o.lineItems
:lineItem是一个变量,在应用中为该变量赋值一个lineItem实例对象,上面查询的语义是:找到:lineItem对象关联的Order实例对象

6. ALL and ANY Expressions
SELECT  emp
FROM  Employee emp
WHERE  emp.salary  >   ALL  (
    
SELECT  m.salary
    
FROM  Manager m
    
WHERE  m.department  =  emp.department)
ALL和ANY表达式用于子查询
上面的emp.salary>ALL(...),表示emp.salary必须大于子查询中返回的所有值;如果子查询没有符合条件的记录,则emp.salary>ALL(...)这个条件为true
将上面例子中的关键字ALL改为ANY(或者是SOME)关键字,则表示emp.salary只要大于子查询中返回的部分值就符合条件;如果子查询没有符合条件的记录,则emp.salary>ANY(...)这个条件为false;如果子查询返回的结果全部都大于或等于emp.salary,则这个条件为false

7. Constructor Expressions
使用constructor expressions可以指定使用特定的构造函数返回实例对象列表,而不是object数组的列表
SELECT  NEW com.xyz.CustomerDetail(c.name, c.country.name)
FROM  customer c
WHERE  c.lastname  =   ' Coss '   AND  c.firstname  =   ' Roxane '

8. 再来几个示例
Find all orders that have line items:
SELECT   DISTINCT  o
FROM   Order  o,  IN (o.lineItems) l
或者:
SELECT  o
FROM   Order  o
WHERE  o.lineItems  IS   NOT  EMPTY

Find all orders that have no line items:
SELECT  o
FROM   Order  o
WHERE  o.lineItems  IS  EMPTY

通过上面这些例子可以看出JPA的查询语言具备较强的对象表达能力

UPDATE、DELETE语句的主要目的是提供bulk update、delete操作
JPA中也声明了一些函数,大部分为SQL标准中的一些基本函数

实现JPA规范的查询语言时,需要重点处理的一个方面是多态查询,语句中的实体类名有可能是abstract的或者supperclass,查询解析器需要能够处理这种多态查询。例如NHibernate(目前版本不知是否改成了Antlr来解析)在分析查询语句时比较简化处理,每遇到实体类都搜索是否有子类存在,如果有则会为每个子类生成一个查询语句,使用JOIN、UNION或者单独执行每个语句再将结果合并(NHibernate不支持Union Subclass),只实现了部分多态能力。要实现完全的多态能力,面对的情况以及需要处理的东西都比较复杂
其它一些细节方面的东西也非常多,例如persistence context可能缓存了一些更新操作,等待Flush时回写数据库,但为了保证查询结果的一致性,执行查询前至少需要先将persistence context中相关实体的更新缓存运用到数据库中

Metadata
详细的元数据声明规范,查阅JPA对annotation、XML descriptor的说明一节

分享到:
评论

相关推荐

    JPA 规范1.0 中文版

    JPA规范1.0中文版, Java 持久化标准. 感谢翻译者.

    JPA规范实现与总结

    JPA规范实现,用JPA来解决可移植问题

    JPA源文件/jpa学习

    jpa jpa规范 jpa源码 jpa jpa规范 jpa源码

    Hibernate4之JPA规范配置详解

    Hibernate4之JPA规范配置详解

    jpa orm规范

    JPA ORM规范:其一,简化现有Java EE和Java SE应用开发工作;其二,Sun希望整合ORM技术,实现天下归一

    jpa2.0 规范文档.zip

    Java persistence api, jpa 2.0最终版使用规范, 资源是压缩包, 下载后解压缩文件,然后重命名persistence-2_0-final-spec文件,添加后缀 .pdf 原始文件的类型时pdf的

    JPA规范 1.0

    JPA document 博文链接:https://eyesofwolf.iteye.com/blog/713441

    ssh2,JPA规范基础框架+ant打包

    ssh2框架基于最新的JPA注解规范,对初学者希望有所帮助

    Java Persistence API(EJB3.0中的 JPA 规范说明)

    Java Persistence API(EJB3.0中的 JPA 规范说明) 。

    基于JPA规范实现hibernate依懒的jar包

    十分全面的通过JPA规范实现hibernate需要用到的jar包

    jpa规范下的shh2配置要点.docx

    jpa规范下的shh2配置要点.docx

    JPA规范注解的javax.persistence包

    JPA规范注解的javax.persistence包 ejb3-persistence.jar

    JPA-1 概述与HelloWorld

    JPA的HelloWorld实现,使用实现JPA规范的Hibernate持久化框架

    Java JPA 学习资料 合集

    JPA 规范部分详细的介绍了 JPA 中实体 Bean 的定义,并介绍了实体 Bean 支持的注释、全新的查询语言、实体管理接口、容器实现规范等内容。 JPA 标准制定过程中充分吸收了目前已经出现的所有持久化技术的所有优点,...

    rsql-jpa-specification:Java库将RSQL转换为Spring Data JPA规范和QueryDSL谓词

    rsql-jpa规范 将RSQL查询转换为org.springframework.data.jpa.domain.Specification或com.querydsl.core.types.Predicate和support实体关联查询。 Maven仓库 将RSQL的rsql-jpa-spring-boot-starter添加到Spring JPA...

    jpa-spec:jpa规范助手

    JPA规范 规范模式。 可以使用SpecificationService来实现规范化。 例子 资料库 @Repository public interface PersonRepository extends JpaRepository< Person> , JpaSpecificationExecutor< Person> { } 또는 ...

    spring+jpa

    JPA 规范要求,配置文件必须命名为 persistence.xml,并存在于类路径下的 META-INF 目录中。该文件通常包含了初始化 JPA 引擎所需的全部信息。Spring 提供的 LocalContainerEntityManagerFactoryBean 提供了非常灵活...

    JPA学习大全.docx

    Spring Data JPA 是 Spring 基于 ORM 框架、JPA 规范的基础上封装的一套JPA应用框架,可使开发者用极简的代码即可实现对数据库的访问和操作。它提供了包括增删改查等在内的常用功能,且易于扩展!学习并使用 Spring ...

    apache-openjpa-3.1.0-binary.zip

    JPA规范要求对实体对象进行某种类型的监视,但是该规范并未定义如何实现此监视。一些JPA提供程序动态生成在用户的Entity对象前面的新子类或代理对象,而其他JPA提供程序使用字节码编织技术来增强实际的Entity类对象...

    JPA学习资料 JPA学习资料

    JPA(Java Persistence API)作为 Java EE 5.0 平台标准的 ORM 规范,将得到所有 Java EE 服务器的支持。Sun 这次吸取了之前 EJB 规范惨痛失败的经历,在充分吸收现 有 ORM 框架的基础上,得到了一个易于使用、伸缩性...

Global site tag (gtag.js) - Google Analytics