Hibernate查询返回所需的结果,但有时会在同一数据上返回空列表

时间:2015-09-03 17:37:18

标签: hibernate spring-mvc

对于我的(Spring / Hibernate 4.3.11)应用程序,一个活动俱乐部组织由成员和成员组织的室内和室外活动,我已经对我的Activity表做了一个Hibernate查询,该表应返回登录的活动。会员是组织者或参与者之一。从概念上讲,它可以被称为"我的活动"。

HQL看起来像:

select a from Activity as a where (a.organizer = :member or :member in elements(a.participants)) order by a.dateFrom asc, a.timeFrom asc

启动应用程序后,查询将返回预期结果。似乎生成了一堆单独的SQL查询(从HQL到SQL的转换对我来说仍然有些神秘!)

在应用程序中点击一下后,突然查询不再返回任何结果。没有进行任何数据更改。

在点击触发以下代码的活动的编辑链接后,似乎会出现问题:

public String getActivityForm(@ModelAttribute("loggedinMember") Member loggedinMember, @PathVariable("id") int id, ModelMap model) {
    Activity activity = service.findActivityById(id);
    if (! activity.getOrganizer().equals(loggedinMember)) {
        //throw exception, you can only edit an activity organized by you
        System.out.println("You are not the organizer of this activity!");
    }
    model.addAttribute("activity", activity);
    return "activityform";  
}

这里没有什么奇怪的事情,所以我真的没有抓住可能引发这个问题的事情。

我查看了生成的SQL,如果没有返回结果,则会更短。 SQL块很长,但我在下面发布。 显然,每行都会生成单独的SQL查询! 我真的迷失了,这个问题在我去了更新版本的Hibernate之后第一次出现了。 所以任何想法......?

生成所需结果的SQL:

Hibernate: 
    select
        activityca0_.id as id1_1_,
        activityca0_.description as descript2_1_ 
    from
        activitycategory activityca0_
Hibernate: 
    select
        activityre0_.id as id1_2_,
        activityre0_.description as descript2_2_ 
    from
        activityregion activityre0_
Hibernate: 
    select
        activity0_.id as id1_0_,
        activity0_.category_id as categor10_0_,
        activity0_.date_from as date_fro2_0_,
        activity0_.date_to as date_to3_0_,
        activity0_.description as descript4_0_,
        activity0_.meetingpoint as meetingp5_0_,
        activity0_.organizer_id as organiz11_0_,
        activity0_.price as price6_0_,
        activity0_.region_id as region_12_0_,
        activity0_.time_from as time_fro7_0_,
        activity0_.time_to as time_to8_0_,
        activity0_.title as title9_0_ 
    from
        activity activity0_ 
    where
        activity0_.organizer_id=? 
        or ? in (
            select
                participan1_.member_id 
            from
                member_activity_subscription participan1_ 
            where
                activity0_.id=participan1_.activity_id
        ) 
    order by
        activity0_.date_from asc,
        activity0_.time_from asc
Hibernate: 
    select
        activityca0_.id as id1_1_0_,
        activityca0_.description as descript2_1_0_ 
    from
        activitycategory activityca0_ 
    where
        activityca0_.id=?
Hibernate: 
    select
        member0_.id as id1_3_0_,
        member0_.active as active2_3_0_,
        member0_.birthdate as birthdat3_3_0_,
        member0_.city as city4_3_0_,
        member0_.email as email5_3_0_,
        member0_.firstname as firstnam6_3_0_,
        member0_.interests as interest7_3_0_,
        member0_.lastname as lastname8_3_0_,
        member0_.lastname_prefix as lastname9_3_0_,
        member0_.loginname as loginna10_3_0_,
        member0_.mobilephone as mobilep11_3_0_,
        member0_.password as passwor12_3_0_,
        member0_.summary as summary13_3_0_ 
    from
        member member0_ 
    where
        member0_.id=?
Hibernate: 
    select
        activityre0_.id as id1_2_0_,
        activityre0_.description as descript2_2_0_ 
    from
        activityregion activityre0_ 
    where
        activityre0_.id=?
Hibernate: 
    select
        activityca0_.id as id1_1_0_,
        activityca0_.description as descript2_1_0_ 
    from
        activitycategory activityca0_ 
    where
        activityca0_.id=?
Hibernate: 
    select
        member0_.id as id1_3_0_,
        member0_.active as active2_3_0_,
        member0_.birthdate as birthdat3_3_0_,
        member0_.city as city4_3_0_,
        member0_.email as email5_3_0_,
        member0_.firstname as firstnam6_3_0_,
        member0_.interests as interest7_3_0_,
        member0_.lastname as lastname8_3_0_,
        member0_.lastname_prefix as lastname9_3_0_,
        member0_.loginname as loginna10_3_0_,
        member0_.mobilephone as mobilep11_3_0_,
        member0_.password as passwor12_3_0_,
        member0_.summary as summary13_3_0_ 
    from
        member member0_ 
    where
        member0_.id=?
Hibernate: 
    select
        activityre0_.id as id1_2_0_,
        activityre0_.description as descript2_2_0_ 
    from
        activityregion activityre0_ 
    where
        activityre0_.id=?
Hibernate: 
    select
        activityca0_.id as id1_1_0_,
        activityca0_.description as descript2_1_0_ 
    from
        activitycategory activityca0_ 
    where
        activityca0_.id=?
Hibernate: 
    select
        member0_.id as id1_3_0_,
        member0_.active as active2_3_0_,
        member0_.birthdate as birthdat3_3_0_,
        member0_.city as city4_3_0_,
        member0_.email as email5_3_0_,
        member0_.firstname as firstnam6_3_0_,
        member0_.interests as interest7_3_0_,
        member0_.lastname as lastname8_3_0_,
        member0_.lastname_prefix as lastname9_3_0_,
        member0_.loginname as loginna10_3_0_,
        member0_.mobilephone as mobilep11_3_0_,
        member0_.password as passwor12_3_0_,
        member0_.summary as summary13_3_0_ 
    from
        member member0_ 
    where
        member0_.id=?
Hibernate: 
    select
        activityca0_.id as id1_1_0_,
        activityca0_.description as descript2_1_0_ 
    from
        activitycategory activityca0_ 
    where
        activityca0_.id=?
Hibernate: 
    select
        activityre0_.id as id1_2_0_,
        activityre0_.description as descript2_2_0_ 
    from
        activityregion activityre0_ 
    where
        activityre0_.id=?
Hibernate: 
    select
        activityca0_.id as id1_1_0_,
        activityca0_.description as descript2_1_0_ 
    from
        activitycategory activityca0_ 
    where
        activityca0_.id=?
Hibernate: 
    select
        participan0_.activity_id as activity1_0_0_,
        participan0_.member_id as member_i2_4_0_,
        member1_.id as id1_3_1_,
        member1_.active as active2_3_1_,
        member1_.birthdate as birthdat3_3_1_,
        member1_.city as city4_3_1_,
        member1_.email as email5_3_1_,
        member1_.firstname as firstnam6_3_1_,
        member1_.interests as interest7_3_1_,
        member1_.lastname as lastname8_3_1_,
        member1_.lastname_prefix as lastname9_3_1_,
        member1_.loginname as loginna10_3_1_,
        member1_.mobilephone as mobilep11_3_1_,
        member1_.password as passwor12_3_1_,
        member1_.summary as summary13_3_1_ 
    from
        member_activity_subscription participan0_ 
    inner join
        member member1_ 
            on participan0_.member_id=member1_.id 
    where
        participan0_.activity_id=?
Hibernate: 
    select
        participan0_.activity_id as activity1_0_0_,
        participan0_.member_id as member_i2_4_0_,
        member1_.id as id1_3_1_,
        member1_.active as active2_3_1_,
        member1_.birthdate as birthdat3_3_1_,
        member1_.city as city4_3_1_,
        member1_.email as email5_3_1_,
        member1_.firstname as firstnam6_3_1_,
        member1_.interests as interest7_3_1_,
        member1_.lastname as lastname8_3_1_,
        member1_.lastname_prefix as lastname9_3_1_,
        member1_.loginname as loginna10_3_1_,
        member1_.mobilephone as mobilep11_3_1_,
        member1_.password as passwor12_3_1_,
        member1_.summary as summary13_3_1_ 
    from
        member_activity_subscription participan0_ 
    inner join
        member member1_ 
            on participan0_.member_id=member1_.id 
    where
        participan0_.activity_id=?
Hibernate: 
    select
        participan0_.activity_id as activity1_0_0_,
        participan0_.member_id as member_i2_4_0_,
        member1_.id as id1_3_1_,
        member1_.active as active2_3_1_,
        member1_.birthdate as birthdat3_3_1_,
        member1_.city as city4_3_1_,
        member1_.email as email5_3_1_,
        member1_.firstname as firstnam6_3_1_,
        member1_.interests as interest7_3_1_,
        member1_.lastname as lastname8_3_1_,
        member1_.lastname_prefix as lastname9_3_1_,
        member1_.loginname as loginna10_3_1_,
        member1_.mobilephone as mobilep11_3_1_,
        member1_.password as passwor12_3_1_,
        member1_.summary as summary13_3_1_ 
    from
        member_activity_subscription participan0_ 
    inner join
        member member1_ 
            on participan0_.member_id=member1_.id 
    where
        participan0_.activity_id=?
Hibernate: 
    select
        participan0_.activity_id as activity1_0_0_,
        participan0_.member_id as member_i2_4_0_,
        member1_.id as id1_3_1_,
        member1_.active as active2_3_1_,
        member1_.birthdate as birthdat3_3_1_,
        member1_.city as city4_3_1_,
        member1_.email as email5_3_1_,
        member1_.firstname as firstnam6_3_1_,
        member1_.interests as interest7_3_1_,
        member1_.lastname as lastname8_3_1_,
        member1_.lastname_prefix as lastname9_3_1_,
        member1_.loginname as loginna10_3_1_,
        member1_.mobilephone as mobilep11_3_1_,
        member1_.password as passwor12_3_1_,
        member1_.summary as summary13_3_1_ 
    from
        member_activity_subscription participan0_ 
    inner join
        member member1_ 
            on participan0_.member_id=member1_.id 
    where
        participan0_.activity_id=?
Hibernate: 
    select
        participan0_.activity_id as activity1_0_0_,
        participan0_.member_id as member_i2_4_0_,
        member1_.id as id1_3_1_,
        member1_.active as active2_3_1_,
        member1_.birthdate as birthdat3_3_1_,
        member1_.city as city4_3_1_,
        member1_.email as email5_3_1_,
        member1_.firstname as firstnam6_3_1_,
        member1_.interests as interest7_3_1_,
        member1_.lastname as lastname8_3_1_,
        member1_.lastname_prefix as lastname9_3_1_,
        member1_.loginname as loginna10_3_1_,
        member1_.mobilephone as mobilep11_3_1_,
        member1_.password as passwor12_3_1_,
        member1_.summary as summary13_3_1_ 
    from
        member_activity_subscription participan0_ 
    inner join
        member member1_ 
            on participan0_.member_id=member1_.id 
    where
        participan0_.activity_id=?
Hibernate: 
    select
        participan0_.activity_id as activity1_0_0_,
        participan0_.member_id as member_i2_4_0_,
        member1_.id as id1_3_1_,
        member1_.active as active2_3_1_,
        member1_.birthdate as birthdat3_3_1_,
        member1_.city as city4_3_1_,
        member1_.email as email5_3_1_,
        member1_.firstname as firstnam6_3_1_,
        member1_.interests as interest7_3_1_,
        member1_.lastname as lastname8_3_1_,
        member1_.lastname_prefix as lastname9_3_1_,
        member1_.loginname as loginna10_3_1_,
        member1_.mobilephone as mobilep11_3_1_,
        member1_.password as passwor12_3_1_,
        member1_.summary as summary13_3_1_ 
    from
        member_activity_subscription participan0_ 
    inner join
        member member1_ 
            on participan0_.member_id=member1_.id 
    where
        participan0_.activity_id=?
Aantal activiteiten: 6
Handling GET request, activities = [nl.drsklaus.activiteitensite.model.Activity@8070e879, nl.drsklaus.activiteitensite.model.Activity@ac6b814e, nl.drsklaus.activiteitensite.model.Activity@e5b2a54b, nl.drsklaus.activiteitensite.model.Activity@97726734, nl.drsklaus.activiteitensite.model.Activity@2d0defe, nl.drsklaus.activiteitensite.model.Activity@f2f57489]

SQL生成空结果:

Hibernate: 
    select
        activityca0_.id as id1_1_,
        activityca0_.description as descript2_1_ 
    from
        activitycategory activityca0_
Hibernate: 
    select
        activityre0_.id as id1_2_,
        activityre0_.description as descript2_2_ 
    from
        activityregion activityre0_
Hibernate: 
    select
        activity0_.id as id1_0_,
        activity0_.category_id as categor10_0_,
        activity0_.date_from as date_fro2_0_,
        activity0_.date_to as date_to3_0_,
        activity0_.description as descript4_0_,
        activity0_.meetingpoint as meetingp5_0_,
        activity0_.organizer_id as organiz11_0_,
        activity0_.price as price6_0_,
        activity0_.region_id as region_12_0_,
        activity0_.time_from as time_fro7_0_,
        activity0_.time_to as time_to8_0_,
        activity0_.title as title9_0_ 
    from
        activity activity0_ 
    where
        activity0_.organizer_id=? 
        or ? in (
            select
                participan1_.member_id 
            from
                member_activity_subscription participan1_ 
            where
                activity0_.id=participan1_.activity_id
        ) 
    order by
        activity0_.date_from asc,
        activity0_.time_from asc
Aantal activiteiten: 0
Handling GET request, activities = []

议程(我的活动)页面的代码如下:

@RequestMapping(value = "/subscribed", method = RequestMethod.GET)
public String home(@ModelAttribute("loggedinMember") Member member, ModelMap model) {

List<Activity> activities = service.findAllActivitiesForMember(member, true);
System.out.println("Aantal activiteiten: " + activities.size());

System.out.println("Handling GET request, activities = " + activities);     
model.addAttribute("activitiessubscribed", activities);
return "myactivities";
}

将服务方法委托给dao方法,该方法如下所示:

@Override
public List<Activity> findAllActivitiesForMember(Member member, boolean upcoming) {

String hql = "select a from Activity as a where (a.organizer = :member or :member in elements(a.participants))";

if (upcoming) {
    hql += " order by a.dateFrom asc, a.timeFrom asc";
} else {
    hql += " order by a.dateTo desc, a.timeTo desc";
}

System.out.println("HQL: " + hql);
Query query = this.getSession().createQuery(hql);

query.setEntity("member", member);
return query.list();
}

使用以下网址:

第一次访问我的活动日程(正常结果: http://localhost:8080/ActiviteitenSite/activities/subscribed

选择特定活动: http://localhost:8080/ActiviteitenSite/activities/3

回头(仍然是正常结果): http://localhost:8080/ActiviteitenSite/activities/subscribed

编辑活动(屏幕显示活动详细信息,不进行提交): http://localhost:8080/ActiviteitenSite/activities/3/edit

再次访问我的议程(结果现在为空): http://localhost:8080/ActiviteitenSite/activities/subscribed

1 个答案:

答案 0 :(得分:0)

我找到了Member对象(在登录期间保存在会话中)被破坏的地方: 在调用getActivityForm处理程序方法时,loggedinMember对象的id值(最初为1000)更改为@PathVariable id参数,该参数是活动的id。 这确实不应该发生,但确实发生在这种方法中。从那时起,Member对象包含id属性的错误值,并且查询不再起作用。仍然是一个mysetry如何以及为什么会发生这种情况。

public String getActivityForm(@ModelAttribute("loggedinMember") Member loggedinMember, @PathVariable("id") int id, ModelMap model) {
Activity activity = service.findActivityById(id);
if (! activity.getOrganizer().equals(loggedinMember)) {
    //throw exception, you can only edit an activity organized by you
    System.out.println("You are not the organizer of this activity!");
}
model.addAttribute("activity", activity);
return "activityform";  
}

编辑: 问题确实是@PathVariable(&#34; id)值与@ModelAttribute(&#34; loggedinMember&#34;)对象的id属性匹配,最后一个被修改。根据SpringMVC文档,这是预期的行为,但恕我直言,这是不需要的和非常不合逻辑的,我认为它是一个严重和令人讨厌的Spring MVC bug。

通过重命名&#34; id&#34;解决了这个问题。 Modelattribute to&#34; activityId&#34;这样就不会发生这种不必要的和意外的匹配。

@RequestMapping(value = "/{activityId}/edit", method = RequestMethod.GET)
public String getActivityForm(@ModelAttribute("loggedinMember") Member loggedinMember, @PathVariable("activityId") int activityId, ModelMap model) {
Activity activity = service.findActivityById(activityId);
if (! activity.getOrganizer().equals(loggedinMember)) {
        //throw exception, you can only edit an activity organized by you
System.out.println("Je bent niet de organisator van deze activiteit!");
}
model.addAttribute("activity", activity);
   return "activityform";   
}