【问题标题】:Spring Roo doesn't add FetchType.LAZY for fields in .aj files, Should I do it manually?Spring Roo 没有为 .aj 文件中的字段添加 FetchType.LAZY,我应该手动添加吗?
【发布时间】:2014-06-29 19:50:28
【问题描述】:

这是几个问题,Spring Roo 应该通过逆向工程为 .aj 文件中的 Set 字段添加 FetchType.LAZY 还是我应该手动执行?

如果 .aj 文件中不存在 FetchType.LAZY,我可以通过查询“SELECT st1 FROM parentTable t1 JOIN FETCH t1.childTable st1”进入选择,对吧?

这里的重点是我可以手动将 FetchType.LAZY 添加到文件中(重构 .aj 文件 > Push In..),然后添加到 .java 文件中(如果我希望 Roo 保持对我的域类的控制,则风险很高)。

关于通过查询,我不能这样做,因为我得到:

> query specified join fetching, but the owner of the fetched association was not present in the select list [FromElement{explicit,not a collection join,fetch join,fetch non-lazy properties,classAlias=ii,role=...domain.Industry.i18nIndustries,
tableName=..I18nIndustry,
tableAlias=i18nindust3_,
origin=..Industry industry2_,
columns={industry2_.IdIndustry ,className=..domain.I18nIndustry}}] 
[select u.idUserName, u.isActiveInd, u.employeeNbr, u.name, c.name as CompanyName, ii.name as IndustryName from Users u JOIN u.idCompany c JOIN c.idIndustry i JOIN FETCH i.i18nIndustries ii WHERE u.idUserName = :username ]

这里是 Roo 生成的 .aj 文件:

privileged aspect Users_Roo_DbManaged {
...    
@ManyToOne
@JoinColumn(name = "IdCompany", referencedColumnName = "IdCompany", nullable = false)
private Company Users.idCompany;  ...

..

privileged aspect Company_Roo_DbManaged {
...
@ManyToOne
@JoinColumn(name = "IdCity", referencedColumnName = "IdCity", nullable = false)
private City Company.idCity;

@ManyToOne
@JoinColumn(name = "IdIndustry", referencedColumnName = "IdIndustry", nullable = false)
private Industry Company.idIndustry; ..

..

    privileged aspect Industry_Roo_DbManaged {    ..
@OneToMany(mappedBy = "idIndustry")
private Set<I18nIndustry> Industry.i18nIndustries; ...

你能告诉我这里发生了什么吗?

Spring MVC 3.2, Roo 1.2.4, MSSql 数据库

谢谢各位! --JR

【问题讨论】:

  • 确认,这是你的HQL在执行[select u.idUserName, u.isActiveInd, u.employeeNbr, u.name, c.name as CompanyName, ii.name as IndustryName from Users u JOIN u.idCompany c JOIN c.idIndustry i JOIN FETCH i.i18nIndustries ii WHERE u.idUserName = :username ]吗?

标签: spring hibernate hibernate-mapping spring-roo


【解决方案1】:

关于

这是几个问题,Spring Roo 应该通过逆向工程为 .aj 文件中的 Set 字段添加 FetchType.LAZY 还是我应该手动执行?

这不是必需的,因为这是这种关系的默认设置(请参阅https://stackoverflow.com/a/13765381/2295657)。

如果 .aj 文件中不存在 FetchType.LAZY,我可以通过查询“SELECT st1 FROM parentTable t1 JOIN FETCH t1.childTable st1”进入选择,对吧?

这使得关系数据急切地加载。我认为您对 LAZY 和 EAGER 模式的含义有误:

  • EAGER:需要在实例加载到内存时加载值(基本和无集合关系属性的默认值)
  • LAZY:加载实例时,代理存储在属性中,当任何尝试获取数据时,从 DB 中加载它(集合关系属性的默认值)

另一方面,加载 LAZY 属性需要在任何尝试获取数据时都处于活动状态的 DB 连接,因此,您必须在非静态 @Transactional 带注释的方法中执行此代码(阅读 @Transactional JavaDoc 了解更多信息)。

我建议您查看 JPA 规范。以我的经验,我很有用。

【讨论】:

    【解决方案2】:

    我发现发生了什么,这是你的 HQL

    [select u.idUserName, u.isActiveInd, u.employeeNbr, u.name, c.name as CompanyName, ii.name as IndustryName from Users u JOIN u.idCompany c JOIN c.idIndustry i JOIN FETCH i.i18nIndustries ii WHERE u.idUserName = :username ]

    我从这个 hql 中了解到,你想获取 i18nIndustries ii 的列表以及那个 perticuler idIndustry i 对吗?

    但是当您在任何对象上使用JOIN FETCH 时,您必须选择主对象来保存子对象,在您的情况下,主对象是idIndustryJOIN FETCH i.i18nIndustries ii 表示“在获取idIndustry 时,同时获取i18nIndustries,链接到idIndustry”。但是您的查询没有获取idIndustry 所以获取没有意义。

    在选择中,您还必须获取i,以便获取的关联(i.i18nIndustries ii)的所有者(i)将出现在选择列表中。因为你的错误是

    查询指定连接抓取,但抓取的所有者 选择列表中不存在关联

    或删除JOIN FETCH 只需使用JOIN

    所以请记住,您想要i18nIndustries ii 的列表,您的查询将变为:(在选择中添加i

    选择 u.idUserName、u.isActiveInd、u.employeeNbr、u.name、c.name 作为 CompanyName, i,ii.name as IndustryName from Users u JOIN u.idCompany c 加入 c.idIndustry i 加入 FETCH i.i18nIndustries ii WHERE u.idUserName = :用户名

    【讨论】:

    • 感谢您提供的详细信息 Amogh,我现在清楚了。
    • 当然啦!谢谢!不幸的是,我得到“投票需要 15 声望”.. 我不确定它是如何工作的,我阅读了教程,据说只需单击向上箭头就足够了。 stackoverflow.com/help/privileges/vote-up
    猜你喜欢
    • 2015-01-05
    • 2013-06-09
    • 1970-01-01
    • 2016-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多