1

I'm using Jboss. I have a bunch of checkboxes which I generated via a producer(@Named, @SessionScoped), the data comes from a mysql database (using hibernate). When I click a checkbox I print out (p:growl) a message (with p:ajax) according to the checkbox clicked. All this works. But each time I click a checkbock, I can see that hibernate executes MANY unneeded queries. In fact there should not be a SINGLE query executed when clicking the checkbox, since the method which I call only takes the profile as an argument and posts a message from a field of it.

Here is the relevant code:

the 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>

the profile controller:

@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);
        }
    }
}

the 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));
    }
}

These are the queries which are executed when I open the site the first time (this is the correct & expected behavior):

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

But when I click a checkbox I see that both queries from above are executed many times - for some checkboxes it executes 15 times, for other 25 times and so on...

What am I doing wrong?

OschtärEi
  • 2,255
  • 3
  • 20
  • 41

1 Answers1

0

Hmm looks like I "fixed" it. But I'm more unsure than ever that what I'm doing is even closely related to as "how one should do it". It would be really nice if someone could tell me if my code is completely stupid and wrong or if I'm going in the right direction here.

I changed my profileProducer like that:

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);
}

Obviously now it won't query the database eveytime - but I still don't understand why it even executes the method.

Am I using completly wrong beans and/or annotations?

Any rebuke / input would be very welcome.

Edit: looks like I programmed "the workaround" (caching, as mentioned in balusc other answer myself).

edit2:

in the end I ended up doing it as balus recommened. I'm getting all the data in a @PostConstruct method and put them in a map (with groupName + formName as a key) and in my getter method I just read them out.

OschtärEi
  • 2,255
  • 3
  • 20
  • 41