简体   繁体   English

休眠,获取,HQL和hashCode()

[英]Hibernate, fetch, HQL and hashCode()

I have a HQL query something ala' 我有一个HQL查询内容'

SELECT myclass 
FROM 
    MyClass myclass JOIN FETCH 
    myclass.anotherset sub JOIN FETCH 
    sub.yetanotherset
...

So, class MyClass has a property "anotherset" , which is a set containing instance of another class, lets call it MyClassTwo. 因此,类MyClass具有属性“ anotherset”,它是一个包含另一个类的实例的集合,我们将其称为MyClassTwo。 And, class MyClassTwo has a property yetanotherset which is a set of a third type of class (with no further associations on it). 并且,类MyClassTwo有一个属性yetanotherset,它是第三类类的集合(没有进一步的关联)。

In this scenario, I'm having trouble with the hashCode implementation. 在这种情况下,我在hashCode实现上遇到了麻烦。 Basically, the hashCode implementation of MyClassTwo, uses the "yetanotherset" property, and on the exact line it accesses the yetanothertest property, it fails with a LazyInitializationException. 基本上,MyClassTwo的hashCode实现使用“ yetanotherset”属性,并且在确切的一行上,它访问yetanothertest属性,但由于LazyInitializationException而失败。

org.hibernate.LazyInitializationException: illegal access to loading collection 

I'm guessing, this is because the data from "yetanotherset" hasn't been fetched yet, but how do I fix this? 我猜测是因为尚未从“ yetanotherset”获取数据,但是如何解决呢? I don't particularly like the idea of dumbing down the hashCode to ignore the property. 我不特别喜欢将hashCode简化为忽略该属性的想法。

Additional question, does HQL ignore fetch=FetchType.EAGER as defined in XML or annotations, it seems like it does. 另一个问题是,HQL是否会忽略XML或批注中定义的fetch = FetchType.EAGER,似乎确实如此。 But I cant verify this anywhere. 但是我在任何地方都无法验证。

Implementing hashCode() using a mutable field is a bad idea: it makes storing the entity in a HashSet and modifying the mutable property impossible. 使用可变字段实现hashCode()是个坏主意:它使将实体存储在HashSet中并无法修改mutable属性。

Implementing it in terms of a collection of other entities is an even worse idea: it forces the loading of the collection to compute the hashCode. 用其他实体的集合来实现它是一个更糟糕的主意:它强制集合的加载来计算hashCode。

Choose a unique, immutable property (or set of properties) in your entity, and implement hashCode based on that. 在您的实体中选择一个唯一的,不可变的属性(或属性集),然后基于该属性实现hashCode。 On last resort, you have the option of using the ID, but if it's autogenerated, you must not put it in a Set before the ID is generated. 最后,您可以选择使用ID,但是如果ID是自动生成的,则在生成ID之前,请勿将其放入Set中。

This is hibernate's most famous exception and it is exactly as you described it. 这是休眠最著名的异常,它与您所描述的完全相同。 The session has been disconnected, transaction closed, and you are attempting to access this collection. 会话已断开连接,事务已关闭,并且您正在尝试访问此集合。 JOIN FETCH in your HQL should force EAGER loading to occur regardless of whether than annotation is present. 无论是否存在注释,HQL中的JOIN FETCH都会强制进行EAGER加载。

I suspect that your annotations are malformed, you have missing or out of date jars, or some other problem of that type. 我怀疑您的注释格式不正确,缺少的jar或过时的jar或其他此类问题。

Bump your Hibernate logging level up to generate the SQL hibernate.SQL=debug and investigate exactly what SQL is being executed up to where you see this exception. 提升您的Hibernate日志记录级别,以生成SQL hibernate.SQL=debug并精确地调查正在执行的SQL,直到您看到此异常为止。 This should indicate to you whether your hibernate configuration is behaving the way you think its configured. 这应该向您指示休眠配置是否以您认为的方式进行配置。

Post more of your code and the logs and someone might be able to help you spot the error. 发布更多的代码和日志,也许有人可以帮助您发现错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM