Hibernate Lazy Loading无效

时间:2016-03-02 05:08:55

标签: hibernate spring-mvc lazy-loading eager-loading

// This is what I have in my Model Class...

    public class Quotation {
    @JoinColumn(name = "party_id", referencedColumnName = "id")
    @ManyToOne (fetch = FetchType.LAZY)
    private Party party;
    }

在我的Controller中,我正在加载Quotation对象:

// Load Quotation object by the Entity Manager:- em.find(Quotation.class, quoteId)

    quotation = quotationService.getQuoteHeadById(quoteId);
    log.debug( " party ID --> "+ quotation.getParty.getId() );

但是我在这个延迟加载中甚至没有得到Party表/对象的Party ID。但是,如果我将获取类型更改为Eager,那么log.debug()会完美地为我提供ID。

我错了什么?

5 个答案:

答案 0 :(得分:0)

要获取LAZY字段,您需要进入交易。你的控制器方法似乎不是跨国的。从Understanding transaction session with lazy loading in Spring JPA Hibernate

获取一个想法

答案 1 :(得分:0)

  

但我没有得到Party表/对象的Party ID   这个懒惰的装载。

以下是@ManyToOne (fetch = FetchType.LAZY)的行为。请注意,当我们在字段vs getter上使用hibernate注释时,行为会有所不同。

在您使用hibernate annotations on the field的实体类中。如果您在实体上调用quotation.getParty.getId()中的getId()方法,则会导致初始化代理(派对对象)并命中数据库以获取它。因此,事务必须处于活动状态,否则会导致抛出lazyinitializationexception

如果意图只是获取实体的Id,则可以放置休眠annotations on the getter methods。这不会初始化代理(派对对象)以返回id,因此不需要活动事务。但访问除id之外的任何其他属性将需要活动事务,并将导致命中数据库。

查看HHH-3718

上的相关错误

因此,在您的派对实体中使用property / getter AccessType而不是字段访问。作为一个例子而不是

@Id
@GeneratedValue(...)
private long id;

将它们放在吸气剂上

@Id
@GeneratedValue(...)
public long getId() { ... }

确保对Party实体的其他字段进行类似的更改。您可以稍后探索使用@Access(AccessType.PROPERTY/FIELD)的其他选项,以获得相同的效果。

转到EAGER

  

但是如果我将fetch类型更改为Eager,那么log.debug()会给我   身份证完美无缺。

这是因为FetchType.EAGER导致预先获取派对实体(无代理),因此我们能够获得派对实体的id和其他属性。请注意,这会导致基于配置的JOIN / extra SELECT查询。

  

我错了什么???

我没有看到任何错误,这都是因为字段vs getter访问类型具有不同的行为。因此,如果您使用文件级访问,Hibernate将初始化代理,即使是根据bug HHH-3718获取关联对象的ID,也可以直到它被解析。

hibernate论坛上关于字段与属性访问类型的相关主题可能会引起关注Field Vs Property access

希望这可以回答您的问题。

答案 2 :(得分:0)

使用它:

状态,Hibernate.initialize(quotation.getParty());

答案 3 :(得分:0)

首先在服务级别设置事务。然后配置hibernate属性,如

<prop key="hibernate.enable_lazy_load_no_trans">true</prop>

我不知道你的配置,但我希望它能运作。 (注意:记住它可能不安全)

答案 4 :(得分:0)

To get party object from quotation object, you have to use left join fetch on your query. Then you will be able to access your party object from quotation object .

Write a jpql query like this:

SELECT q from Quotation q left join fetch q.party p 

Then you will not get "could not initialize proxy - no Session" error . By the way, it is a very common error. It means you are trying to access a object which you did not fetch by your query. Hope this answer help.