复选框单击执行许多hibernate查询

时间:2013-12-06 07:45:26

标签: ajax hibernate jsf-2 primefaces jboss7.x

我正在使用Jboss。 我有一堆复选框,我是通过生产者(@Named, @SessionScoped)生成的,数据来自mysql数据库(使用hibernate)。当我单击复选框时,我会根据单击的复选框打印出(p:growl)一条消息(带p:ajax)。这一切都有效。但每次单击一个checkbock,我都可以看到hibernate执行了许多不需要的查询。实际上,单击复选框时不应执行SINGLE查询,因为我调用的方法仅将profile作为参数并从其字段发布消息。

以下是相关代码:

jsf-part:

    <p:growl id="checkMessages" />
    <p:dataTable var="_profile" value="#{profileProducer.getProfilesByFormAndName('test','test')}" >
        <p:column>
            <p:selectBooleanCheckbox value="#{orderController.checkedProfiles[_profile]}">
                <p:ajax update="@([id$=checkMessages])" listener="#{profileProducer.profileCheck(_profile)}" />
            </p:selectBooleanCheckbox>
        </p:column>
    </p:dataTable>

配置文件控制器:

@Named
@SessionScoped
public class ProfileController implements Serializable  {

    private List<Profile> temporaryCheckedProfileList = new ArrayList<Profile>();

    public void profileCheck(Profile profile) {
        System.out.println(profile);
        String message = profile.getMessage();
        if (message == null || message.equals(""))
            return;
        if (!temporaryCheckedProfileList.contains(profile)) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(message));
            temporaryCheckedProfileList.add(profile);
        } else {
            temporaryCheckedProfileList.remove(profile);
        }
    }
}

profileProducer:

@RequestScoped
@Named
public class ProfileProducer  {

    @Inject
    private ProfileRepository profileRepository;
    @Inject
    private GroupRepository groupRepository;

    public List<Profile> getProfilesByFormAndName(@New String formName,@New  String groupName) {
        return  profileRepository.getProfilesByGroup(groupRepository.getGroupByFormAndName(formName, groupName));
    }
}

这些是我第一次打开网站时执行的查询(这是正确和预期的行为):

Hibernate: select * from group group0_ inner join form form1_ on group0_.form_id=form1_.id where group0_.name=? and form1_.name=? limit ?

Hibernate: select * from profile profile0_ inner join group_profile groupprofi1_ on profile0_.id=groupprofi1_.profile_id inner join group group2_ on groupprofi1_.group_id=group2_.id where group2_.id=1 order by groupprofi1_.sort_nr asc

但是当我点击一个复选框时,我发现上面的两个查询都执行多次 - 对于某些复选框,它执行15次,其他25次执行...等等...

我做错了什么?

1 个答案:

答案 0 :(得分:0)

嗯,好像我“固定”了它。但是我比以往任何时候都更不确定我所做的事情甚至与“如何做到”密切相关。 如果有人能告诉我我的代码是完全愚蠢和错误,还是我在这里朝着正确的方向前进,那将是非常好的。

我改变了我的profileProducer:

private Map<String, List<Profile>> cachedProfiles = new HashMap<String, List<Profile>>();

public List<Profile> getProfilesByFormAndName(String formName, String groupName) {
    String key = formName + groupName;
    if (!cachedProfiles.containsKey(key)) {
        List<Profile> profiles = profileRepository.getProfilesByGroup(groupRepository.getGroupByFormAndName(formName, groupName));
        cachedProfiles.put(key, profiles);
    }
    return cachedProfiles.get(key);
}

显然现在它不会查询数据库的eveytime - 但我仍然不明白为什么它甚至会执行该方法。

我使用完全错误的bean和/或注释吗?

非常欢迎任何指责/投入。

编辑: 看起来我编写了“解决方法”(缓存,如balusc其他人自己提到的那样)。

EDIT2:

最后我最终按照balus的推荐做了。 我在@PostConstruct方法中获取所有数据并将它们放在一个映射中(以groupName + formName作为键),在我的getter方法中我只读出它们。