1

I am new to JSF 2.0 and Primefaces but have decided to create my application using them seeing the primefaces showcase.

I have completed my application but have noticed that it is extremely slow. I have placed some system.out.println in various places to see what is being called and I noticed that sometimes methods in my controller such as methods that call my DAO to retrieve values from the Database are being called up to 6 times on one event! My pages have a lot of datatables in them so sometimes multiple datatables * 6 calls for each list being populated in each table seems like this is what is causing the slowness.

I am not sure what I have done wrong or if I did anything wrong but in my controller for instance I have a method that might look like this,

public List<Addresses> getAddresses() {
     List<Addresses> addr = systemDao.getAddresses(userBean.userId);
     return addr;
}

in the view I will then call this method like on a datatable element to display the result.

When I first load it it will only call this once but when I click maybe a button to open a dialog with completely unrelated data this getAddresses() might be called 3 - 6 times and it has nothing to do with the data the I am requesting during the current action. Is anyone familiar with this and how I could maybe speed up my application?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
newtoJSF
  • 27
  • 1
  • 5

1 Answers1

5

You should not put business/database logic in getters. They are intented to only return the data, not to initialize/load/populate the bean's data. You should be doing business/database logic inside bean's @PostConstruct, action method or any event methods, which are all invoked only once, not inside getters.

private List<Addresses> addr;

@PostConstruct
public void init() {
     addr = systemDao.getAddresses(userBean.userId);
}

public List<Addresses> getAddresses() {
     return addr;
}

If you really need to do it in the getter for some exotic reason, then you need to introduce lazy loading.

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • I have tried this method but every time I did that I would get exception of 'Constructor threw exception' so I thought it was the wrong way of doing it. Again I am calling my DAO so I am not sure if that is where the problem is occuring when calling it in my managed bean constructor – newtoJSF Jan 12 '11 at 14:43
  • Just handle the exception. Use a `try-catch` or add a `throws` clause. This is unrelated to JSF, it's just basic Java. – BalusC Jan 12 '11 at 14:47
  • hrmm I guess it just seems weird to me that I would be throwing exceptions like this in my constructor, thanks though, I will give it a shot. – newtoJSF Jan 12 '11 at 14:56
  • Why would it be weird? What do you want your application to do when DB is down or the query is after all bogus? Show an error page, right? Throwing the exception is the way to do. – BalusC Jan 12 '11 at 14:57
  • no I understand that but the thing is my DB is not down and the query is not bogus and its throwing an exception every time. I am not very good at Java but to me it seems that getting that Exception is saying that something isn't right with putting a call to the DAO in the constructor. Now I am sure you are correct, there has to be something else wrong with my application because it does not like it when I call my dao from within my constructor. It only will compile and run when I call the DAO within a method such as a getter. – newtoJSF Jan 12 '11 at 15:00
  • Oh you got an exception but you didn't understand it? You should not be ignoring it. It contains information about the cause of the problem. You know, once the cause is *understood*, the solution speaks for itself. If you actually can't decipher the exception, then share it with us so that we can explain you what it is trying to tell you about the cause of the problem. – BalusC Jan 12 '11 at 15:01
  • I have extended my DAO as an abstract class, this might be the problem. I have multiple Controllers that use the same DAO which is atuowired and I attempted to create an abstract class which contains the DAO set methods and the DAO variables and extended each controller with that. Maybe this approach is not valid – newtoJSF Jan 12 '11 at 15:03
  • Sounds perfectly valid though. Abstraction is always good. Any bad things would at highest only result in errors during compile, not in exceptions during runtime. – BalusC Jan 12 '11 at 15:04
  • weird, I have no idea, but whatever I do I will always get a NullPointerException whenever I call a DAO method within a constrcutor / postconstruct . – newtoJSF Jan 12 '11 at 15:06
  • Thanks for the help I guess I am going to have to do some more investigating – newtoJSF Jan 12 '11 at 15:06
  • So the DAO class is been injected as managed property or resource? Then the constructor is indeed the wrong place for the job. Using a `@PostConstrut` method should however perfectly work. See also the "See also" link in the answer for more detail. – BalusC Jan 12 '11 at 15:12
  • the dao class is extended to each controller and it is a managed property I believe. I was however getting errors on the post construct, I am going to try it again though. – newtoJSF Jan 12 '11 at 15:28
  • ahh that @PostConstruct did in fact work! Thank you for taking the time I really appreciate it! – newtoJSF Jan 12 '11 at 15:33