Spring Roo没有为.aj文件中的字段添加FetchType.LAZY,我应该手动完成吗?

时间:2014-06-29 19:50:28

标签: spring hibernate hibernate-mapping spring-roo

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

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

这里的要点是我可以手动将FetchType.LAZY添加到文件中(Refactor .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

2 个答案:

答案 0 :(得分: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带注释的方法中执行此代码(read { {1}} JavaDoc了解更多信息)。

我建议你看看JPA规范。根据我的经验,我非常有用。

答案 1 :(得分:0)

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

  

[选择u.idUserName,u.isActiveInd,u.employeeNbr,u.name,c.name作为CompanyName,ii.name作为IndustryName来自用户u JOIN u.idCompany c JOIN c.idIndustry i JOIN FETCH i.i18nIndustries ii WHERE u.idUserName =:username]

我从这个hql中理解的是,您想要获取i18nIndustries ii的列表以及该相关的idIndustry i是否正确?

但是当你在任何对象上使用JOIN FETCH时,你必须选择主对象来保存子对象,在你的情况下,主对象是idIndustryJOIN FETCH i.i18nIndustries ii表示&#34;在抓取idIndustry时,还会抓取i18nIndustries,链接到idIndustry&#34;。但是你的查询并没有提取idIndustry所以提取没有任何意义。

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

  

查询指定的连接提取,但提取的所有者   选择列表中没有关联

或删除JOIN FETCH只需使用JOIN

因此请记住,您需要i18nIndustries ii的列表,您的查询将变为:(在{中添加i

  

选择u.idUserName,u.isActiveInd,u.employeeNbr,u.name,c.name as   CompanyName, i ,ii.name为来自用户的IndustryName联合u.idCompany c   JOIN c.idIndustry i JOIN FETCH i.i18nIndustries ii WHERE u.idUserName   =:用户名