2016-03-02 76 views
0
// 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; 
    } 

在我控制我加载报价对象是这样的:Hibernate的延迟加载不工作

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

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

,但我不能在这个懒惰,甚至得到对方表/对象的方ID加载。但是,如果我将提取类型更改为Eager,那么log.debug()会完美地为我提供ID。

我错了吗?

+0

尝试@ManyToOne(fetch = FetchType.LAZY,可选= false) –

+0

您可以提供查询代码吗? –

+0

@Eva Mariam:(fetch = FetchType.LAZY,可选= false)没有解决问题。 – obsolete

回答

0

对于获取LAZY字段,您需要在事务中。你的控制器方法似乎不是跨国的。从得到一个想法:Understanding transaction session with lazy loading in Spring JPA Hibernate

+0

我刚刚在ServiceImpl中声明了Transactional方法。仍然有同样的问题......“无法初始化代理 - 没有会议”。 的ServiceImpl是如下: @Transactional(传播= Propagation.SUPPORTS,只读=真) 公共报价getQuoteHeadById(长quoteId){ \t返回quotationDao.getQuoteHeadById(quoteId); \t} – obsolete

+0

好吧,那么也得检查你的项目配置了。事务必须在应用程序上下文中正确配置。你有任何github链接? –

+0

没有兄弟,我没有在github这个项目。但作为参考,@Transaction在其他所需的方法之上工作正常。只是在这个特定的情况下有问题。 – obsolete

0

,但我不是在 这个延迟加载甚至得到对方表/对象的方ID。

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

在您的实体类中,您使用hibernate annotations on the field。如果你调用getId()方法(如quotation.getParty.getId()),它会导致初始化(对象的)代理并触发数据库来获取它。所以交易必须是活跃的,否则将导致投掷lazyinitializationexception

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

看一看相关的bug在HHH-3718

所以,在你方实体使用属性/吸气接入类型,而不是实地访问。作为一个例子,而不是

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

把他们放在干将

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

确保您对Party实体的其他领域类似的变化。您稍后可以探索另一种使用@Access(AccessType.PROPERTY/FIELD)的选项来获得相同的效果。

移动到EAGER

但是,如果我改变了获取类型跃跃欲试,那么log.debug()完美地给我 的ID。

这是因为FetchType.EAGER结果在热切地获取党的实体(无代理)前面,所以我们能够获得的ID和党的实体的其他属性。请注意,这会导致基于配置的JOIN /额外SELECT查询。

我错了吗?

我没有看到任何错误,这都是因为字段与getter访问类型有不同的行为。因此,如果您使用的是字段级别的访问权限,Hibernate会初始化代理,即使获取关联对象的ID为bug HHH-3718或直到它解决。

以及有关领域VS属性访问类型可能会感兴趣Field Vs Property access

希望这回答您的查询有关休眠论坛相关主题。

+0

不知道为什么这已被投票。提供原因将有助于更新答案或相应地进行更正。 –

+0

我没有降低它的声誉,你知道我还没有15声望。非常感谢你的清晰画面。我会尝试。 – obsolete

+0

@Backbencher我明白了。顺便说一句,有兴趣看看我上面的回答是否帮助你了解为什么懒加载不工作以及如何使它工作? –

0

使用这样的:

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

0

首先在服务级别设置交易。然后配置休眠属性,如

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

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

2

要从引用对象中获取party对象,必须在查询中使用左连接提取。然后,您将能够从报价对象访问您的派对对象。

写这样的JPQL查询:

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

这样你就不会得到“无法初始化代理 - 没有会话”错误。顺便说一下,这是一个非常常见的错误。这意味着你正试图访问一个你没有通过查询获取的对象。 希望这个答案帮助。

+0

这没有奏效。而这实际上并不是延迟加载的主题,我认为。如果我得到Quotation对象,我必须通过hibernate实体管理器延迟加载Party ID – obsolete