Friday, July 16, 2010

Hibernate error : Cannot instantiate abstract class or interface:

If you ever saw this error message "Cannot instantiate abstract class or interface: " in retrieving a list of objects, there could be one of the two reasons.

Assuming you have an object model where there's an abstract parent entity which is inherited by a list of children entities and each entity is mapped to a table, then

1) First make sure that records are consistent. That is, when you try to retrieve a record, hibernate is retrieving a list of parent objects and according to the data model design, each parent object must have subsequent child object. So, for each row in a parent table, there should be a matching record in the sub-table. For some reasons, if the record is missing the sub-table, when hibernate returns the data, it will throw the exception since it cannot instantiate the abstract parent class.

2) It is possible that your data are intact, but the problem is the changes of the data model in the code base. In our class, we removed one subclass but we forget to migrate the data and remove the sub-table that is being mapped to the subclass. Hence, when hibernate retrieves a list of parent objects, it is seeing the right data but since our data model are not consistent, it's throwing an exception.

Thursday, July 8, 2010

Merging landscape and portrait PDFs into one.

In one of my previous posts, I wrote about the problems with merging different pdfs into one pdf package. I followed the sample code posted here to have different pdfs merged into one.

However, there's one problem with that code. The code is fine if you combined pdfs of the same size. But as in my case where I have pdfs of both portrait and landscape, landscape pdfs are cut off. Originally I thought the way to solve this problem is rotating those landscape pdfs and then merge. However, rotating pdf works only when you output the merged pdf using a PdfStamper. The code uses PdfWriter which takes a Document object to write the pdf contents.

After several hours of googling the solution, I realized that, the solution is not by rotating the pdf, but buy changing pdf size. When document.newPage() is called it's generating a blank page and contents are being written to the new page in the following lines of code. The default page size is portrait size, so if we change the page size and copied over the content, the new PDF would be copied without being chopped off. Only one line of code is needed to solve the problem, which is
document.setPageSize(pdfReader.getPageSize(currentPageNumber))

Here pdfReader must be pointing the current pdf that is being copied over. Another important thing to note is that setPageSize() method has to be put before document.newPage(). If you put it after, then the changed page size will be effective only for the next page, not the current one.

Monday, July 5, 2010

Dynamic including of a page inside <rich:modalPanel>

I've used <rich:modalPanel> inside a dataTable successfully in the past. I did it in two ways. For simple <rich:modalPanel> i.e a modal panel that requires no actions except for just displaying information, I just put <rich:modalpanel> inside the dataTable. This is not really a good solution since, one modal panel is associated to multiple instances of object. And I have conversation time out experience when I tried to open up the modal panel and close it multiple times quickly.

The other way to use modal panel is to send parameters to the modal panel. This is useful especially if you have a form inside a modal panel which you want to do processing. In this scenario, modal panel is declared outside the data table. Every time, the panel is open, an object reference can be passed to a variable in the backing bean so that we know which object we want to associate the currently active panel with. Obviously, this requires more steps on the programmer side.

Honestly, I do not have a good experience working with modal panel. In theory, modal panel sounds a good solution for many user interfaces, but I still find that <rich:modalPanel> to be lacking in some features that I would want. Also, it doesn't allow nested forms inside the panel.

So, my last annoying experience with <rich:modalPanel> is when I want to include a page inside a modal panel. And the page is dyanmic, i.e, given the object information, I would like to include a certain page. So, I have <a4j:include sr="#{object1.name}.xhtml" inside the modal panel. It turns out that I cannot do that and every time I tried to access the page, object1.name returns an emtpy string. I think what is happening is that <rich:modalPanel> is being rendered on the page load. It's not dynamic rendering. Therefore, the object value is not there and it's not returning the appropriate page. I need to do a little bit more debugging regarding my assumptions. But when I can add a static page to be included in the modal panel, it worked just fine..