- 浏览: 197820 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (121)
- java_基础 (26)
- java_web (15)
- javascript (9)
- extJS (0)
- dwr (0)
- guobin_ETL (1)
- guobin_ssh (17)
- guobin_webservice (1)
- guobin_jbpm (0)
- guobin_jquery (0)
- guobin_acegi (1)
- guobin_poi/jxl (2)
- guobin_multiThread (0)
- guobin_名称解释 (0)
- guobin_FLEX (0)
- guobin_php (0)
- guobin_ORACLE (1)
- guobin_mysql (0)
- guobin_linux (0)
- guobin_powerDesigner (0)
- guobin_visol (0)
- guobin_ER/STUDIO (0)
- guobin_jmesa (0)
- guobin_weblogic (0)
- guobin_kettle (0)
- guobin_一路风雨 (5)
- guobin_spark (0)
- java_xml (7)
- guobin_规则引擎 (0)
- 插件开发 (2)
- 软件管理 (3)
- spring mvc (2)
- java_jni (1)
- eclipse (1)
- oracle (0)
- 项目学习笔记 (1)
- java多线程学习记录 (9)
- websphere性能设置和日常维护 (2)
- (1)
- 系统软件架构设计 (1)
- ces (1)
- 需求分析 (2)
- IBM-CICS GATEWAY (1)
- 工具使用 (1)
- 网络信息安全编程 (1)
最新评论
-
yzh__:
学习一个
Hibernate 自关联注解方式 -
xiaoyahuang:
"2)将Sysdeo Plugin下的DevLoad ...
eclipse项目引用 -
guobin6125:
guobin6125 写道sfasshahhah评论的评论
欢迎使用Kit! -
guobin6125:
sfass
欢迎使用Kit! -
guobin6125:
tst23
欢迎使用Kit!
----------------------------------
Spring,FetchType.LAZY和FetchType.EAGER什么区别?
FetchType.LAZY:懒加载,加载一个实体时,定义懒加载的属性不会马上从数据库中加载。 2、FetchType.EAGER:急加载,加载一个实体时,定义急加载的属性会立即从数据库中加载。 3、比方User类有两个属性,name跟address,就像百度知道,登录后用户名是需要显示出来的,此属性用到的几率极大,要马上到数据库查,用急加载;而用户地址大多数情况下不需要显示出来,只有在查看用户资料是才需要显示,需要用了才查数据库,用懒加载就好了。所以,并不是一登录就把用户的所有资料都加载到对象中,于是有了这两种加载模式。
------------------------------------------------------------------------------
CascadeType.PERSIST:级联新增
CascadeType.MERGE:级联合并
CascadeType.REFRESH:级联刷新
CascadeType.REMOVE:级联删除
CascadeType.ALL:以上四种都是
本文列出几个“EJB 学习阶段总结:JBoss下发布一个Toy企业应用”开发测试过程中遇到的几个问题。
1. Hibernate 懒加载有一定局限性:EJB远程调运时Hibernate懒加载Session失效
通过实例说明:给Entity类中添加Transformer类,Transformer与UserCard存在一对一的单向关联,如下:
- @Entity(name="Transformer")
- @Table(name="k_transformer")
- public class Transformer implements Serializable{
- private Long id;
- private UserCard userCard;
- @Column
- @Id
- @GeneratedValue
- public Long getId() {
- return id;
- }
- public void setId(Long id) {
- this.id = id;
- }
- @OneToOne(
- targetEntity = com.home.po.UserCard.class,
- <strong><span style="color: #ff0000;"><em>fetch = FetchType.LAZY</em></span></strong>,
- cascade = { CascadeType.ALL })
- @Cascade( { org.hibernate.annotations.CascadeType.ALL } )
- @JoinColumn(name = "UserCard_id")
- @ForeignKey(name = "TRANSFORMER_TO_USERCARD_FK")
- public UserCard getUserCard() {
- return userCard;
- }
- public void setUserCard(UserCard userCard) {
- this.userCard = userCard;
- }
- }
注意OneToOne属性设定FetchType必须是LAZY,因为我们测试的是Hibernate懒加载
添加一个HibernateTest Session Bean,如下:
- public interface TransformerService {
- public void persist(Transformer t);
- public void analysis(Long id);
- public Transformer analysisRemote(Long id);
- }
- @Stateless
- @Remote(TransformerService.class)
- @Local(TransformerServiceLocal.class)
- public class TransformerServiceSession implements TransformerServiceLocal {
- @PersistenceContext(unitName="com.home.po")
- protected EntityManager em;
- @TransactionAttribute(TransactionAttributeType.REQUIRED)
- public void persist(Transformer t) {
- em.persist(t);
- }
- @TransactionAttribute(TransactionAttributeType.REQUIRED)
- public void analysis(Long id) {
- Transformer t = em.find(Transformer.class, id);
- analysisEntity(t);
- }
- <span style="color: #000000;">private void analysisEntity(Transformer t) {
- System.out.println(t.getUserCard());
- }</span>
- @TransactionAttribute(TransactionAttributeType.REQUIRED)
- public Transformer analysisRemote(Long id) {
- return em.find(Transformer.class, id);
- }
- }
在客户端先向数据库中插入一条数据,在运行如下代码段:
- public void analysis() throws NamingException {
- ……
- TransformerService service = (TransformerService) ctx.lookup("home-test-all/TransformerServiceSession/remote");
- service.analysis(new Long(1));
- Transformer tra = service.analysisRemote(new Long(1));
- analysisEntityInRemote(tra);
- }
- <span style="color: #000000;">private void analysisEntityInRemote(Transformer t) {
- System.out.println(t.getUserCard());
- }</span>
注意上述加红倾斜的代码段描述的方法analysisEntity,analysisEntityInRemote作用都是相同的,取出Transformer中UserCard属性,但是运行结果却如下,TransformerServiceSession 中的analysisEntity运行良好,Jboss Console控制台打印输出如下信息: 而Remote端Eclipse Console口抛出Session无效的异常:
- Exception in thread "main" org.hibernate.LazyInitializationException: could not initialize proxy - no Session
- at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:62)
- at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:116)
- at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:166)
- at com.home.po.UserCard_$$_javassist_0.toString(UserCard_$$_javassist_0.java)
- at java.lang.String.valueOf(Unknown Source)
- at java.io.PrintStream.println(Unknown Source)
- at com.home.ear.test.HibernateTestClient.analysisEntityInRemote(HibernateTestClient.java:41)
- at com.home.ear.test.HibernateTestClient.analysis(HibernateTestClient.java:37)
- at com.home.ear.test.HibernateTestClient.main(HibernateTestClient.java:47)
具体原因,继续研究中……
2 hibernate.jdbc.batch_size与 hibernate.jdbc.fetch_size初始值大小对Hibernate工作效率的影响:
修改Persistence Entity EJB模块中persistence.xml中Properties属性可以改变hibernate.jdbc.batch_size与 hibernate.jdbc.fetch_size的值,我做了如下两组测试,如下:
如下一,改变hibernate.jdbc.batch_size的大小,插入1000条User连续三次,记录每次插入时间,并计算出三次平均时间: 如下二改变Change hibernate.jdbc.fetch_size大小,从数据库中取出2000条和4000条数据,记录取出时间,如下: 如上两组数据,可以得出结论,在这个应用中hibernate.jdbc.batch_size设置为20-30之间Hibernate工作效率最好;而hibernate.jdbc.fetch_size是值设置为40左右Hibernate的工作效率最好
3 比较@OneToMany下@JoinColumn和@JoinTable的差别(对性能的影响)
@JoinColumn不产生级联表,将一方的主键存放在另一方的表中,如下,为JoinColumn的Entity Bean配置
以User与Friend为例:
- @OneToMany (
- targetEntity=com.home.po.Friend.class,
- fetch=FetchType.LAZY,
- cascade = { CascadeType.ALL })
- @Cascade( { org.hibernate.annotations.CascadeType.ALL } )
- @JoinColumn(name="userId")
- @ForeignKey(name="USER_TO_FRIEND_FK")
- public List<Friend> getFriends() {
- return friends;
- }
这种配置下 产生表如下图:
@JoinTable产生级联表,将双方的主键存放在一张独立的表中,如下为@JoinTable的配置
- @OneToMany (
- targetEntity=com.home.po.Friend.class,
- fetch=FetchType.LAZY,
- cascade = { CascadeType.ALL })
- @Cascade( { org.hibernate.annotations.CascadeType.ALL } )
- @JoinTable(name="k_user_friend",
- joinColumns = @JoinColumn(name = "USER_ID"),
- inverseJoinColumns = @JoinColumn(name = "FRIEND_ID"))
- @ForeignKey(name = "k_user_friend_FK",
- inverseName = "k_user_friend_FK_R")
- public List<Friend> getFriends() {
- return friends;
- }
这种配置下 产生表如下图:
如上用直线标出的5张表就是5对一对多关系产生的级联表,它里面存储两个表的主键。
这两种处理对数据的插入和存取有什么影响,就这一问题做如下测试:
1 分别在两种配置下通过EJB向数据库中插入2000个User 5次,记录每次时间,求出平均时间;
2 分别在两种配置下通过EJB从数据库中取出10000条数据5次,记录每次时间,求出平均时间;
结果如下两组图分别是JoinTable和JoinColumn下的测试数据
从上图比较可以得出结论:
1 JoinTable下操作数据库花费的时间要长于JolinColumn;
2 JolinColumn下节省的时间约为JoinTable下的2.5%;
分析原因:JoinTable花费时间多的原因是JoinTable下生成的中间表,要存取数据时都要查询中间的级联表,所以花费时间多;
4 测试建立外键与不建立外键两种情况下对存取数据库的影响
如上面3中都是设置外键的情况下测试的,下面我们在JoinColumn下做一组不设置外键的测试,不设置外键Annotation相当简单就是在原来的基础上去掉@ForeignKey标记,如下
- @OneToMany (
- targetEntity=com.home.po.Friend.class,
- fetch=FetchType.LAZY,
- cascade = { CascadeType.ALL })
- @Cascade( { org.hibernate.annotations.CascadeType.ALL } )
- @JoinColumn(name="userId")
- public List<Friend> getFriends() {
- return friends;
- }
为了对比我们假设两种情况,一是JolinColumn下配置ForeignKey,二是JolinColumn下不配置ForeignKey,在两种情况下做如下测试:
1 分别在两种配置下通过EJB向数据库中插入2000个User 5次,记录每次时间,求出平均时间;
2 分别在两种配置下通过EJB从数据库中取出10000条数据5次,记录每次时间,求出平均时间;
测试结果如下面两张表所示:
从上面两组图我们可以得出如下结论:
1 ForeignKey对数据库的存取影响比较大,特别是数据库的查询
2 设置ForeignKey可以减少数据库存取的时间
3 设置ForeignKey插入数据库节省的时间是不设置ForeignKey的5.5%,查询时则可以节省6.5%
--------------------------------------------------------------------------------------------------
说明:以上时间有一定局限性,只是在当前这种情况下测试的结果,不过可以当做参考。
发表评论
-
OpenSessionInViewFilter失效问题解决(SSH2)
2012-07-19 14:07 2318今天在用Hibernate延迟加载时,显示到界面出现如下问题: ... -
Hibernate 自关联注解方式
2012-07-18 18:08 10884Hibernate自关联(使用注解) Hib ... -
hibernate 缓存机制
2012-07-18 11:54 1082CacheConcurrencyStrategy有五种缓 ... -
Spring事务的传播行为和隔离级别[transaction behavior and isolated level]
2012-07-17 23:43 0事务的传播行为和隔离级别[transaction beh ... -
EJB中7个事务属性(PROPAGATION_REQUIRED等)以及5个隔离属性
2012-07-17 23:42 0EJB中7个事务属性(PROPAGATION_REQUI ... -
junit测试之hiberante延迟加载问题
2012-07-17 22:25 0junit测试之hiberante延迟加载问题 ... -
Hibernate SQL方言 (hibernate.dialect) Spring配置文件applicationContext.xml
2012-07-17 07:56 8696Hibernate SQL方言 (hibernate.d ... -
hibernate注解 关系映射 -多对多
2012-07-16 23:23 976使用Hibernate Annotations 维护多对 ... -
spring 中配置sqlserver2008
2012-07-16 23:12 1058不得不说的在 MS SQL SERVER 下的 JDBC ... -
BeanCreationException: No unique bean of type
2012-07-16 13:04 1067我定义了一个基类接口BaseDao,下面有些update\sa ... -
Spring BeanBean的作用域及生命周期
2012-06-20 10:25 1737一、Spring Framework支持五种作用域(其中 ... -
Struts 1 和 Struts 2 的线程安全
2012-06-20 10:24 845昨天人问我Struts 2是怎么保证全局变量的线程安全 ... -
学习Spring必学的Java基础知识(1)----反射
2012-05-22 13:40 783http://www.iteye.com/topic/1123 ... -
Hibernate总结篇
2012-04-26 07:47 1359一、HQL经验总结: HQL ... -
Hibernate HQL语句的拼写
2012-04-22 19:11 1045Hibernate HQL语句的拼写 ... -
HQL中如何实现select top n这样的功能?
2012-04-22 19:09 2588HQL中如何实现select top n这样的功能? ... -
使用strtuts2的iterator标签循环输出二维数组和嵌套集合
2012-04-22 17:31 1289其实都一样的嵌套对象跟二维数组。先看看嵌套对象 ... -
hibernate注解 关系映射
2012-04-17 17:12 11001)一对一外键关联映射(单向) @OneToOne(c ... -
Hibernate 注解及简单实例
2012-04-17 16:09 719hibernate注解 1、@Entity(name= ...
相关推荐
Hibernate的CascadeType属性说明 Hibernate框架中,CascadeType是hibernate的重要属性之一,它控制着实体之间的级联操作。CascadeType是hibernate中的枚举类型,定义了多种级联操作,包括REFRESH、PERSIST、REMOVE...
2. **@JoinTable**:多对多关系通常需要一个中间表来存储双方的关联,`@JoinTable`用来定义这个中间表,包括它的名字、连接的列名等。 ```java @Entity public class User { @ManyToMany @JoinTable(name = "user...
* 双向一对多映射:在多端使用 @ManyToOne 和 @JoinColumn 注解,在一端使用 @OneToMany 和 mappedBy 注解,指定关联属性名。 * 双线一对一映射:基于外键使用 @OneToOne 注解,基于主键使用 Hibernate 的扩展注解。...
"Hibernate注解一对多,多对一"是两个常见的关系映射类型,适用于处理实体类之间的复杂关联。 一、一对多关系 在现实世界中,例如一个部门有多个员工,这就是一对多的关系。在Hibernate中,我们可以使用`@...
在Hibernate中,关系注解用于在实体类中定义不同类型的数据库关系,如一对一、一对多、多对多等。以下是关于Hibernate关系注解的详细说明: 1. **一对一外键关联映射(单向)** 使用`@OneToOne`注解实现一对一关系...
本教程将深入探讨如何在Hibernate中使用注解来实现实体类的配置,特别是关注一对多和多对一的关系映射。 **一、Hibernate注解基础** 在Hibernate 3.2之后,引入了注解支持,使得开发者不再需要XML配置文件来定义...
总结来说,Hibernate注解极大地简化了Java应用的数据库操作,通过注解我们可以定义实体、关联、缓存策略等,使得代码更简洁,同时也提高了开发效率。理解和熟练运用这些注解是成为高效Hibernate开发者的关键。在实践...
- **@OneToMany**和**@ManyToMany**:分别表示一对多和多对多的关联关系,通常需要使用`@JoinColumn`或`@JoinTable`来定义关联表或关联列。 #### 五、特殊属性注解 - **@Temporal**:用于处理日期时间类型的属性,...
1. **注解位置**:@OneToOne注解通常放在关联对象的属性上,表示当前类的这个属性与另一个类的对象形成一对一的关系。 2. **targetEntity**:指定被关联实体的类名,如果不指定,Hibernate会默认查找同一包下的同名...
`@JoinTable`注解可以用来定义中间表的详细信息,包括表名、连接字段等。 3. **关系的维护**: 在双向多对多关联中,你需要小心地维护两边的关系。例如,当你在一个学生对象中添加一门课程,你也需要在课程对象中...
在Hibernate中,可以通过`@ManyToMany`注解定义多对多关系,并使用`@JoinTable`定义连接表。例如,Student实体和Course实体的多对多关系: ```java @Entity public class Student { @ManyToMany @JoinTable...
同时,`cascade`属性可以设置级联操作,如`CascadeType.ALL`会将删除、保存等操作级联到关联对象。 2. **避免循环引用**:在双向关联中,如果不妥善处理,可能导致无限递归或内存溢出问题。通常,我们会指定一方...
本教程将重点讲解如何在Hibernate中实现多对一的映射关系,采用的是注解方式进行配置。 **一、多对一关系** 在数据库设计中,多对一关系表示一个实体可以与另一个实体的多个实例相关联。例如,一个部门可以有多名...
- `CascadeType`: 通过`@OneToMany`或`@OneToOne`的`cascade`属性,可以设置级联操作,比如`CascadeType.PERSIST`、`CascadeType.REMOVE`等,使得对一方的操作自动应用到另一方。 - `FetchType.LAZY` 或 `FetchType....
### Hibernate注解与关系映射详解 #### 一、Hibernate注解基础 **1.1 @Entity** - **概述**:`@Entity`用于标记一个Java类为实体类,表明它是一个持久化对象,可以映射到数据库表。 - **参数**: - `name`:可选...
在Java的持久化框架Hibernate中,单向一对多关联映射是常见的数据关系处理方式,尤其是在处理数据库中的实体类和表之间的关系时。本主题主要关注如何使用注解来实现这种映射。Hibernate通过注解使得对象关系映射...
在Hibernate中,注解用于定义实体类、属性、关联关系等,使得Hibernate能够自动处理这些对象与数据库表之间的映射。 1. **实体类注解**:在Hibernate中,一个Java类可以被标记为数据库中的一个表,这通常使用`@...
7. **级联操作**:为了简化操作,可以设置`@OneToMany`的`cascade`属性,如`CascadeType.ALL`,使得对父对象的操作(如保存、删除)会自动影响到关联的子对象。 8. **懒加载与急加载**:默认情况下,`@OneToMany`...
Hibernate Annotation是一套用于声明式地配置Java持久化对象与数据库表之间映射关系的注解API,它属于Hibernate框架的一部分。在处理一对多关系时,Hibernate Annotation提供了便捷的方式来表达实体之间的关联。本文...