Hi Folks,
I’m using LazyQueryContainer 1.2.9 with vaadin 6.6.4 and a hibernate EntityManager and I’m getting the exception shown below.
My table is successfully loaded with the first 49 items. The above exception occurs when the 50th item is loaded. The Table is set to display 25
lines and I specify a container batchsize of 50.
The key parts of my code are below. Note that when creating EntityManager(…) I’ve tried using both ‘true’ and ‘false’ for the second argument specifing if the app is responsible for transaction management.
According to debug output, there are no “TRANSACTION commit” or close messages from my code after the last “TRANSACTION begin”.
Sep 9, 2011 3:19:55 PM com.vaadin.Application terminalError
SEVERE: Terminal error:
java.lang.IllegalStateException: EntityManager is closed
at org.hibernate.ejb.EntityManagerImpl.getSession(EntityManagerImpl.java:89)
at org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:272)
at org.vaadin.addons.lazyquerycontainer.EntityQuery.loadItems(EntityQuery.java:121)
at org.vaadin.addons.lazyquerycontainer.LazyQueryView.queryItem(LazyQueryView.java:246)
at org.vaadin.addons.lazyquerycontainer.LazyQueryView.getItem(LazyQueryView.java:224)
at org.vaadin.addons.lazyquerycontainer.LazyQueryContainer.getItem(LazyQueryContainer.java:176)
at org.vaadin.addons.lazyquerycontainer.LazyQueryContainer.getContainerProperty(LazyQueryContainer.java:186)
at com.vaadin.ui.AbstractSelect.getContainerProperty(AbstractSelect.java:745)
at vortex.console.ui.AssetsTable.getAssetFromItem(AssetsTable.java:917)
at vortex.console.ui.AssetsTable.access$2(AssetsTable.java:902)
at vortex.console.ui.AssetsTable$5.generateCell(AssetsTable.java:462)
at com.vaadin.ui.Table.refreshRenderedCells(Table.java:1572)
at com.vaadin.ui.Table.enableContentRefreshing(Table.java:2313)
at com.vaadin.ui.Table.changeVariables(Table.java:2159)
at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.handleVariableBurst(AbstractCommunicationManager.java:1299)
at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.handleVariables(AbstractCommunicationManager.java:1219)
at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.doHandleUidlRequest(AbstractCommunicationManager.java:735)
at com.vaadin.terminal.gwt.server.CommunicationManager.handleUidlRequest(CommunicationManager.java:296)
at com.vaadin.terminal.gwt.server.AbstractApplicationServlet.service(AbstractApplicationServlet.java:501)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at vortex.db.EntityManagerRequestFilter.doFilter(EntityManagerRequestFilter.java:69)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:279)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Sep 9, 2011 3:19:55 PM com.vaadin.Application terminalError
SEVERE: Terminal error:
java.lang.ArrayIndexOutOfBoundsException: 25
at com.vaadin.ui.Table.paintContent(Table.java:2496)
at com.vaadin.ui.AbstractComponent.paint(AbstractComponent.java:755)
at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.writeUidlResponce(AbstractCommunicationManager.java:954)
at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.paintAfterVariableChanges(AbstractCommunicationManager.java:841)
at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.doHandleUidlRequest(AbstractCommunicationManager.java:767)
at com.vaadin.terminal.gwt.server.CommunicationManager.handleUidlRequest(CommunicationManager.java:296)
at com.vaadin.terminal.gwt.server.AbstractApplicationServlet.service(AbstractApplicationServlet.java:501)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at vortex.db.EntityManagerRequestFilter.doFilter(EntityManagerRequestFilter.java:69)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:279)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
2011-09-09 15:19:55,461 DEBUG [vortex.console.ui.AssetsTable]
transactionEnd: TRANSACTION END
Java code below:
public class AssetsTable extends Table {
private AdminConsoleApplication app;
private AssetManager assetMgr;
private int linesPerPage = 25;
private EntityContainer<Asset> container;
public void init() {
String m = "init";
log.debug(m, "Initializing");
assetMgr = AssetManager.getInstance();
log.debug(m, "Attach Transaction Listener");
attachVaadinTransactionListener();
log.debug(m, "Populate Table");
populateAndConfigureTable();
log.debug(m, "Ready");
}
/**
* We are using session-per-request pattern with Hibernate. By using
* Vaadin's transaction listener we can easily ensure that session is closed
* on each request without polluting our program code with extra logic.
*/
private void attachVaadinTransactionListener() {
app.getContext().addTransactionListener(new TransactionListener() {
private static final long serialVersionUID = -3558981058139390335L;
@Override
public void transactionStart(Application application,
Object transactionData) {
String m = "transactionStart";
// Transaction listener gets fired for all (Http) sessions
// of Vaadin applications, checking to be this one.
if (application != app)
return;
if (getEntityManager().getTransaction().isActive() == false) {
log.debug(m, "TRANSACTION START");
getEntityManager().getTransaction().begin();
}
}
@Override
public void transactionEnd(Application application,
Object transactionData) {
String m = "transactionEnd";
// Transaction listener gets fired for all (Http) sessions
// of Vaadin applications, checking to be this one.
if (application != app)
return;
if (RequestHandler.hasEntityManager() &&
getEntityManager().getTransaction().isActive() == true) {
log.debug(m, "TRANSACTION END");
getEntityManager().getTransaction().commit();
}
}
});
}
/**
* Helper function to get EntityManager.
* @return EntityManager
*/
private EntityManager getEntityManager() {
return RequestHandler.getEntityManager();
}
protected void populateAndConfigureTable() {
String m = "populate";
log.debug(m, "Configure Table");
setStyleName("assettable");
setSizeFull();
setWidth("100%");
// Allow selection of rows
setSelectable(true);
// Multi selection
setMultiSelect(true);
// Immediately notify server on events
setImmediate(true);
setColumnCollapsingAllowed(true);
setColumnReorderingAllowed(true);
setPageLength(linesPerPage);
/*
* Create container
*/
loadAssets();
/*
* Add the column IDs and Labels in order shown.
* Must do this after container is created.
*/
log.debug(m, "Adding Columns");
columnIds.add(ID_DEV_PHONE_NUMBER); columnLabels.add("Device Phone Number");
columnIds.add(ID_DEV_PRIMARY_COUNTRY); columnLabels.add("Device Country");
columnIds.add(ID_USER_NAME); columnLabels.add("User's Name");
columnIds.add(ID_OWNER_NAME); columnLabels.add("Owner From User");
columnIds.add(ID_USER_EMAIL); columnLabels.add("User's Name");
columnIds.add(ID_ASSET_TAG); columnLabels.add("Asset Tag");
columnIds.add(ID_OS_NAME); columnLabels.add("OS Name");
columnIds.add(ID_MOBILE_PROVIDER); columnLabels.add("Mobile Provider");
columnIds.add(ID_HW_VENDOR); columnLabels.add("HW Vendor");
columnIds.add(ID_HW_MODEL); columnLabels.add("HW Model");
columnIds.add(ID_DEV_TYPE); columnLabels.add("Device Type");
columnIds.add(ID_RADIO_TYPE); columnLabels.add("Radio Type");
columnIds.add(ID_CREATED); columnLabels.add("Registered");
columnIds.add(ID_UPDATED); columnLabels.add("Last Update");
columnIds.add(ID_STATUS); columnLabels.add("Status");
/*
* These properties are not visible, but required.
*/
container.addContainerProperty(ID_DBID, Long.class, 0, true, true);
container.addContainerProperty(ID_ID, String.class, "", true, true);
/*
* Define each column in the container.
*/
for (int i = 0; i < columnIds.size(); ++i) {
String id = columnIds.get(i).toString();
/*
* Adds a new property to the definition.
* @param propertyId Id of the property.
* @param type Value class of the property.
* @param defaultValue Default value of the property.
* @param readOnly Read only state of the property.
* @param sortable Sortable state of the property.
* @return always true.
*/
Class<?> propClass = String.class;
if (id.equals(ID_CREATED) || id.equals(ID_UPDATED))
propClass = Date.class;
container.addContainerProperty(id, propClass, "", true, true);
}
if (log.isDebugOn()) {
@SuppressWarnings("unchecked")
Collection<String> ids = (Collection<String>) container.getContainerPropertyIds();
Iterator<String> iter = ids.iterator();
log.debug(m, "Property IDs from container:");
while (iter.hasNext()) {
String id = iter.next();
log.debug(m, "Property ID=<%s>", id);
}
}
setVisibleColumns(columnIds.toArray());
setColumnHeaders(columnLabels.toArray(new String[0]
));
}
protected void loadAssets() {
String m = "loadAssets";
log.debug(m, "Get EntityManager");
EntityManager em = getEntityManager();
/*
* EntityContainer JavaDoc:
* Constructor which configures query definition for accessing JPA entities.
* @param entityManager The JPA EntityManager.
* @param applicationManagedTransactions True if application manages transactions instead of container.
* @param detachedEntities True if entities are detached from PersistenceContext.
* @param compositeItems True f items are wrapped to CompositeItems.
* @param entityClass The entity class.
* @param batchSize The batch size.
* @param nativeSortPropertyIds Properties participating in the native sort.
* @param nativeSortPropertyAscendingStates List of property sort directions for the native sort.
*/
log.debug(m, "Create LazyQueryContainer");
container = new EntityContainer<Asset>(em,
false, // True if application manages transactions instead of container.
true, // True if entities are detached from PersistenceContext.
true, // True if items are wrapped to CompositeItems.
Asset.class, // The entity class.
linesPerPage * 2, // The batch size.
new Object[] { ID_DBID }, // Properties participating in the native sort.
new boolean[] { true }); // List of property sort directions for the native sort.
log.debug(m, "Add Container data source");
// Set table container
setContainerDataSource(container);
log.debug(m, "Creating GeneratedColumn classes");
/*
* Primary User full name
*/
addGeneratedColumn(ID_USER_NAME, new ColumnGenerator() {
public Component generateCell(Table source,
final Object itemId, Object columnId) {
String m = "generateCell-" + ID_USER_NAME;
Asset asset = getAssetFromItem(itemId, m);
if (asset == null) {
return null;
}
Entity entity = EntityTool.getByType(asset, EntityType.USER);
if (entity == null) {
log.debug(m, "No User entity found");
return null;
}
String value = EntityTool.getName(entity);
if (value == null) {
log.debug(m, "No value found");
return null;
}
log.debug(m, "Value=<%s>", value);
Label label = new Label(value);
return label;
}
});
... lots more column generators ....