在使用spring mvc
和hibernate
的{{1}}应用中,jpa
正在使用 78个加入创建一个过于复杂的查询连接应该是必要的。我正在使用hibernate
。为了简化问题和实验,我在相关实体中注释了许多属性,并且还将父类中的代码剪切并粘贴到子类中以减少继承量。这减少了应该包含在连接中的表的数量为8.但是当我在其中一个实体上尝试InhertanceType.JOINED
时,hibernate会生成不应包含的连接。有人可以请我帮我隔离代码中的问题吗?
您可以查看应包含在连接中的8到12个类的类图 by clicking on this link。这是一个JPEG文件,您可以通过单击它在浏览器中放大。连接中可能只包含8到12个类,但 hibernate在连接中包含另外12个不相关的表,这是完全没必要的。为什么?
问题的原因是EntityManager.persist()
类的持有数据类型的包名错误。因此,applicationService.java
完成的select
是错误包的同名实体的entitymanager
。
关于它的奇怪部分是,日食似乎没有抱怨不同的包装。该体系结构是select
调用包含controller
和service layer
的{{1}},然后调用applicationService.java
图层,其中包含applicationServiceImpl.java
和repository
。错误的包位于repository.java
但不包含在repositoryImpl.java
或service layer
中。我不知道为什么eclipse没有抱怨这个。问题直到运行时才出现。
我认为弗拉德的回答是被接受的,因为他提供了几轮非常清晰且有用的解决方法。
答案 0 :(得分:3)
虽然这种相互连接的设计从OOP的角度来看是有效的,但你必须记住,你正在处理关系数据库,因此过多的继承会损害性能。
您当前的查询根实体是Person,并且提供的图表具有误导性,因为它没有说Person是LivingSubject,它是RimEmtity。
rimEntity.classCode标记为lazy但我看到Hibernate尝试外连接。这不应该发生,因为第二个选择应该加载,所以我怀疑代码和错误不同步,因为在CD类中找不到这种关联:
left outer join TS ivlts2_ on cd1_.VALID_TIME_HXITCE_HJID=ivlts2_.HJID
让我们再来一个@ManyToOne,LivingSubject.birthTime
left outer join TS ts5_ on person0_.birthTime_HJID=ts5_.HJID
所有这些都与整个Person类层次结构的@ManyToOne关联有关。
一种可能的“解决方案”:
尝试设置此属性:
hibernate.max_fetch_depth=0
这将禁用外部连接,然后Hibernate将使用其他选择,但这可能会对性能造成更大的影响。
使用auto-generated code and hbmddl是一个糟糕的设计决定。您的数据库模式应该由增量更新脚本生成,并且您的Hibernate映射应该将数据库表映射到域模型类。
拥有如此多的关系会对性能造成严重影响,因此没有解决问题的灵丹妙药。
您应首先设计db表和查询,然后确定哪个是最适合您应用程序需求的域模型。
答案 1 :(得分:1)
(代表问题作者发布了解决方案,将其移至答案帖)。
问题的原因是applicationService.java
类对于要保留的数据类型具有错误的程序包名称。因此,由select
完成的entitymanager
是同名错误包实体的select
。
奇怪的是,Eclipse似乎并没有抱怨其他软件包。该体系结构是,控制器调用包含applicationService.java
和applicationServiceImpl.java
的服务层,然后调用包含repository.java
和repositoryImpl.java
的存储库层。错误的程序包位于服务层,但不在控制器层或存储库层。我不知道为什么Eclipse对此没有抱怨。该问题直到运行时才出现。
我将弗拉德的答案标记为已接受,因为他提供了几轮非常明确和有用的解决方法。