Hello,
I’ve got a database table with no foreign keys to related tables. But I need to show the related information, so I decided to create an own Query and QuertFactory for LazyQueryContainer.
(There are more than 10000 rows in source table.)
Here’s my code, the QueryFactory:
import javax.persistence.EntityManager;
import org.vaadin.addons.lazyquerycontainer.Query;
import org.vaadin.addons.lazyquerycontainer.QueryDefinition;
import org.vaadin.addons.lazyquerycontainer.QueryFactory;
public class AuditlogsExtQueryFactory implements QueryFactory {
private EntityManager entityManager;
private QueryDefinition definition;
public AuditlogsExtQueryFactory(EntityManager entityManager) {
super();
this.entityManager = entityManager;
}
public void setQueryDefinition(QueryDefinition definition) {
this.definition = definition;
}
@Override
public Query constructQuery(QueryDefinition qd) {
return new AuditlogsExtQuery(entityManager, definition, new Object {"id"}, new boolean {true} );
}
}
And the Query:
import com.vaadin.data.Item;
import com.vaadin.data.util.BeanItem;
import javax.persistence.EntityManager;
import org.vaadin.addons.lazyquerycontainer.Query;
import org.vaadin.addons.lazyquerycontainer.QueryDefinition;
[...]
public class AuditlogsExtQuery implements Query {
private EntityManager entityManager;
private QueryDefinition definition; // not used
private String criteria = "";
private ConverterUtils<AuditlogsExt> converterUtils;
private String rowPropertyMap;
public AuditlogsExtQuery(EntityManager entityManager, QueryDefinition definition,
Object sortPropertyIds, boolean sortStates) {
super();
System.out.println("init");
this.entityManager = entityManager;
this.definition = definition;
this.converterUtils = new ConverterUtils<>();
this.rowPropertyMap = new String {"id", "event", "source", "target", "clientInfo"};
for (int i = 0; i < sortPropertyIds.length; i++) {
if (i == 0) {
criteria = " ORDER BY";
} else {
criteria += ",";
}
criteria += " a." + sortPropertyIds[i]
;
if (sortStates[i]
) {
criteria += " ASC";
} else {
criteria += " DESC";
}
}
}
@Override
public int size() {
System.out.println("size");
return this.entityManager.createQuery("SELECT count(a) FROM Auditlogs a WHERE a.validto > CURRENT_DATE", Long.class)
.getSingleResult()
.intValue();
}
@Override
public List<Item> loadItems(int startIndex, int count) {
System.out.println("loaditems - startIndex: " + startIndex + " - count: " + count);
javax.persistence.Query query = entityManager.createQuery("SELECT a.id, a.event, a.source, a.target, a.clientInfo FROM Auditlogs a JOIN Users u ON a.usersId = u.id WHERE a.validto > CURRENT_DATE " + criteria);
query.setFirstResult(startIndex);
query.setMaxResults(count);
List<Object> result = query.getResultList();
// need to convert Object to real entity - use BeanUtils - is it a good solution???
List<AuditlogsExt> resultExt = this.converterUtils.convertToEntityList(AuditlogsExt.class, result, this.rowPropertyMap);
List<Item> items = new ArrayList<Item>();
for (AuditlogsExt alext : resultExt) {
BeanItem bi = new BeanItem<AuditlogsExt>(alext);
items.add(bi);
}
return items;
}
@Override
public void saveItems(List<Item> addedItems, List<Item> modifiedItems, List<Item> removedItems) {
throw new UnsupportedOperationException("Not supported.");
}
@Override
public boolean deleteAllItems() {
throw new UnsupportedOperationException("Not supported.");
}
@Override
public Item constructItem() {
return new BeanItem<AuditlogsExt>(new AuditlogsExt());
}
}
[/i]
[/i]
[i]
[i]
Ok, let’s use it:
[...]
LazyQueryContainer logs = new LazyQueryContainer(new AuditlogsExtQueryFactory(auditlogsService.getEntityManager()), "id", 50, true);
logs.addContainerProperty("id", Long.class, 0L, true, true);
logs.addContainerProperty("event", String.class, "", true, true);
Grid grid = new Grid();
grid.setContainerDataSource(logs);
[...]
The grid is shown with some data, but then I gave a big, fat exception (console log):
[...]
init
size
loaditems - startIndex: 0 - count: 50
loaditems - startIndex: 50 - count: 50
loaditems - startIndex: 100 - count: 50
ápr. 19, 2016 12:54:07 DU com.vaadin.server.DefaultErrorHandler doDefault
SEVERE:
java.lang.RuntimeException: Unable to get item id for index: 123 from container using Container.Indexed#getIdByIndex() even though container.size() > endIndex. Returned item id was null. Check your container implementation!
at com.vaadin.data.ContainerHelpers.getItemIdsUsingGetIdByIndex(ContainerHelpers.java:90)
at org.vaadin.addons.lazyquerycontainer.LazyQueryContainer.getItemIds(LazyQueryContainer.java:655)
at com.vaadin.server.communication.data.RpcDataProviderExtension.pushRowData(RpcDataProviderExtension.java:367)
at com.vaadin.server.communication.data.RpcDataProviderExtension.access$900(RpcDataProviderExtension.java:65)
at com.vaadin.server.communication.data.RpcDataProviderExtension$2.requestRows(RpcDataProviderExtension.java:293)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:158)
at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:118)
[...]
What did I do wrong?
And what is there a better way to select from a “no foreign key table”?
[/i]
[/i]