hibernate 注解 一对一 延迟加载,为什么就不行呢,求老师帮忙呀,受不了了,

时间:2021-07-18 20:33:43
有2张表,很简单,一个是Person,一个Address,采用一对一单向共享主键,外键关联,插入新数据都正常进行了,可是查询的时候,总是不能延迟加载,
模型如下:(省略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);

#5


补充说明
实现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);

#5


补充说明
实现OpenSessionInView可以采用很多技术:
 Servlet——过滤器
 Struts2——拦截器
 Spring —— AOP
使用OpenSessionInView必须满足Session的线程单例
一个线程分配一个Session,在该线程的方法中可以获得该Session, 具体使用ThreadLocal——其实是一个线程为KEY的Map,