模型如下:(省略set,get)
@Entity(name="person")
public class Person {
@Id
private int id;
@Column
private String name;
@OneToOne(cascade=CascadeType.ALL,fetch=FetchType.LAZY)
@JoinColumn(name="id")
@LazyToOne(LazyToOneOption.PROXY)
@Fetch(FetchMode.SELECT)
private Address address;
}
@Entity(name="address")
public class Address {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
@Column
private String addr;
}
我这样执行查询的:
Person p = (Person)getSession().load(Person.class,2);
p.getName();
注意,我没有执行而控制台上打出的sql却是N+1,如下:
Hibernate:
select
person0_.id as id1_0_,
person0_.name as name1_0_
from
person person0_
where
person0_.id=?
Hibernate:
select
address0_.id as id0_0_,
address0_.addr as addr0_0_
from
address address0_
where
address0_.id=?
而我将12行改为:
@Fetch(FetchMode.JOIN)
控制台就会打出左级联,这当然是正确的的:
Hibernate:
select
person0_.id as id1_1_,
person0_.name as name1_1_,
address1_.id as id0_0_,
address1_.addr as addr0_0_
from
person person0_
left outer join
address address1_
on person0_.id=address1_.id
where
person0_.id=?
可我想用@Fetch(FetchMode.SELECT)进行延迟加载,不是每次我都会用到“Address“这个对象的,
就是说,但我执行“p.getAddress()”,的时候,才会执行:
Hibernate:
select
address0_.id as id0_0_,
address0_.addr as addr0_0_
from
address address0_
where
address0_.id=?
这是我的目的,↑
我配置的应该没问题吧,我来回来去试过很多次了,我的环境是jdk6,框架spring3+hibernate4,我以为是spring3的问题,后来我进行了最纯净版的,只用到hibernate4包,也是这样的问题,(额,hibernate3也是如此)怎么办呀?老师们,帮帮忙吧,太纠结了。。。
另外:我上面的模式,我把它称作——
一对一,(这是肯定的)
共享主键,(ID都是一样的)
单向,(因为我只要求通过过的Person的时候,带出Address,不打算查询Address的时候带出Person)
外键关联,(因为先insert 外表Address,然后利用生成的主键,赋予Person再进行insert)
上面的称呼对吗?没有理解错吧。。。
那个那个,延迟加载的问题,怎么办呀???
在线等。
5 个解决方案
#1
没有人知道吗
#2
真的没人知道吗
#3
我也是同样的问题,
#4
OpenSessionInView技术把Session的关闭延迟到View组件运行完乊后
如果用延迟加载必须使用OpenSessionInView技术,否则在取数据时,session已经关闭了
Hibernate的支持hibernate.cfg.xml
配置文件中: <property name="current_session_context_class">thread</property> 然后调用:
Person p = (Person)getSession().load(Person.class,2);
如果用延迟加载必须使用OpenSessionInView技术,否则在取数据时,session已经关闭了
Hibernate的支持hibernate.cfg.xml
配置文件中: <property name="current_session_context_class">thread</property> 然后调用:
Person p = (Person)getSession().load(Person.class,2);
#5
补充说明
实现OpenSessionInView可以采用很多技术:
Servlet——过滤器
Struts2——拦截器
Spring —— AOP
使用OpenSessionInView必须满足Session的线程单例
一个线程分配一个Session,在该线程的方法中可以获得该Session, 具体使用ThreadLocal——其实是一个线程为KEY的Map,
实现OpenSessionInView可以采用很多技术:
Servlet——过滤器
Struts2——拦截器
Spring —— AOP
使用OpenSessionInView必须满足Session的线程单例
一个线程分配一个Session,在该线程的方法中可以获得该Session, 具体使用ThreadLocal——其实是一个线程为KEY的Map,
#1
没有人知道吗
#2
真的没人知道吗
#3
我也是同样的问题,
#4
OpenSessionInView技术把Session的关闭延迟到View组件运行完乊后
如果用延迟加载必须使用OpenSessionInView技术,否则在取数据时,session已经关闭了
Hibernate的支持hibernate.cfg.xml
配置文件中: <property name="current_session_context_class">thread</property> 然后调用:
Person p = (Person)getSession().load(Person.class,2);
如果用延迟加载必须使用OpenSessionInView技术,否则在取数据时,session已经关闭了
Hibernate的支持hibernate.cfg.xml
配置文件中: <property name="current_session_context_class">thread</property> 然后调用:
Person p = (Person)getSession().load(Person.class,2);
#5
补充说明
实现OpenSessionInView可以采用很多技术:
Servlet——过滤器
Struts2——拦截器
Spring —— AOP
使用OpenSessionInView必须满足Session的线程单例
一个线程分配一个Session,在该线程的方法中可以获得该Session, 具体使用ThreadLocal——其实是一个线程为KEY的Map,
实现OpenSessionInView可以采用很多技术:
Servlet——过滤器
Struts2——拦截器
Spring —— AOP
使用OpenSessionInView必须满足Session的线程单例
一个线程分配一个Session,在该线程的方法中可以获得该Session, 具体使用ThreadLocal——其实是一个线程为KEY的Map,