I tried to implement pagination in google app engine (Java), but I am not able to achieve. It is working only forward pagination and reverse pagination is not able to achieved.
I tried storing the previous cursor value through HTTP request as below:
JSP file:
<a href='/myServlet?previousCursor=${previousCursor}'>Previous page</a>
<a href='/myServlet?nextCursor=${nextCursor}'>Next page</a>
Servlet file:
String previousCursor = req.getParameter("previousCursor");
String nextCursor = req.getParameter("nextCursor");
String startCursor = null;
if(previousCursor != null){
startCursor = previousCursor;
}
if(nextCursor != null){
startCursor = nextCursor;
}
int pageSize = 3;
FetchOptions fetchOptions = FetchOptions.Builder.withLimit(pageSize);
if (startCursor != null) {
fetchOptions.startCursor(Cursor.fromWebSafeString(startCursor));
}
Query q = new Query("MyQuery");
PreparedQuery pq = datastore.prepare(q);
QueryResultList<Entity> results = pq.asQueryResultList(fetchOptions);
for (Entity entity : results) {
//Get the properties from the entity
}
String endCursor = results.getCursor().toWebSafeString();
req.setAttribute("previousCursor", startCursor);
req.setAttribute("nextCursor", endCursor);
With this I am able to retain the previous cursor value, but unfortunately the previous cursor seems to be invalid.
I also tried using reverse() method, but it is of no use. It work same as forward.
So is the any way to implement proper pagination (forward and backword) in google app engine (Java)?
I found similar one that was posted in 2010. Here also the answer was to use Cursor. But as I shown above it is not working.
Pagination in Google App Engine with Java
If you are familiar with JPA you can give it a try.
Have tested it and pagination works in GAE.
I think they support JPA 1.0 as of now.
What I tried was, created an Employee entity.
Created DAO layer and persisted few employee entities.
To have a paginated fetch, did this:
Query query = em.createQuery("select e from Employee e");
query.setFirstResult(0);
query.setMaxResults(2);
List<Employee> resultList = query.getResultList();
(In this example we get first page which has 2 entities. Argument to
setFirstResult would be start index and argument to setMaxResult would be your page size)
You can easily change the arguments to query.setFirstResult and setMaxResults
and have a pagination logic around it.
Hope this helps,
Regards,
Related
I'm using JPA with a Native Query that returns about 13k registers. I thought to use Stream API from Java 8, but the result is not coming.
I Can't paginate because the result will populate a combo box
My repository sends the Stream
I added the #Transactional(readOnly = true) to make it work
#Query(value = "select * from mytable", native = true)
Stream<MyTable> getTableStream()
#Transactional(readOnly = true)
public Stream<MyTable> getTableStream() {
return repository.getTableStream()
}
#GetMapping(value = "/table", produces = MediaType.APPLICATION_STREAM_JSON_VALUE)
#Transactional(readOnly = true)
public ResponseEntity<Stream<MyTable>> getMailingClient() {
Stream<MyTable> body = service.getTableStream();
return ResponseEntity.ok(body);
}
All links and resources I found about stream do not show the implementation of the return JSON with Spring rest API.
My frontend is Angular 6, and nearest I got was one custom object with no result
Loading all 13k records into a combo box sounds like a very slow solution. I would recommend implementing a search based on like query. Something like this:
#Query("SELECT * FROM mytable WHERE name like ':name%'")
Stream<MyTable> getTableStream(#Param("name") String name);
But if you really want to load all of the records, you can use a java.util.Collection or java.util.List instead of a stream.
Collection<MyTable> getTableStream();
So I have a problem in jooq about getting data in spring-boot transaction.
I use a transaction to save the base data, and then I want to use jooq to get these data. But I found that what I fetched is null.
String sql = dslContext.select().from(Tables.SALES_INVENTORY).getSQL();
System.out.println(sql);
Result<Record> fetch1 = dslContext.select().from(Tables.SALES_INVENTORY).fetch();
System.out.println(fetch1);
String groupbySql =
dslContext
.select(Tables.SALES_INVENTORY.ITEM_ID, sum(Tables.SALES_INVENTORY.ON_HAND_QTY))
.from(Tables.SALES_INVENTORY)
.groupBy(Tables.SALES_INVENTORY.ITEM_ID)
.getSQL();
System.out.println(groupbySql);
Result<Record2<UUID, BigDecimal>> fetch =
dslContext
.select(Tables.SALES_INVENTORY.ITEM_ID, sum(Tables.SALES_INVENTORY.ON_HAND_QTY))
.from(Tables.SALES_INVENTORY)
.groupBy(Tables.SALES_INVENTORY.ITEM_ID)
.fetch();
System.out.println(fetch);
List<SalesInventoryEntity> all = salesInventoryRepository.findAll();
all.forEach(s -> System.out.println(s));
Jooq's SQL is correct, but can't find and data return as if I use JPA #Transactional to do my test method. And I use jpa-repository to get data, it found the right data.
So my main problem is how can I get the right data in JPA transactional?
Here is what I used to init the base data. It's a test method, and its class is #Transactional, so this means that the method is also #Transactional?
public void initSalesInventories() {
List<SalesInventoryEntity> salesInventories = Lists.newArrayList();
ItemEntity itemEntity = itemRepository.findById(itemId1).get();
int i = 0;
for (StockLocationEntity stockLocationEntity : stockLocationEntities) {
SalesInventoryEntity salesInventoryEntity = new SalesInventoryEntity();
salesInventoryEntity.setStockLocation(stockLocationEntity);
salesInventoryEntity.setSalesOrganization(usSalesOrgEntity);
salesInventoryEntity.setItem(itemEntity);
salesInventoryEntity.setItemClass(ItemClass.SALEABLE);
salesInventoryEntity.setOnHandQty(100);
salesInventoryEntity.setReservedQty(0);
salesInventoryEntity.setAvailableQty(100);
salesInventoryEntity.setLeadTime(5);
DocumentType[] values = DocumentType.values();
salesInventoryEntity.setDocType(values[i % 7]);
String code = "TO-201906112010000" + i;
i++;
salesInventoryEntity.setDocCode(code);
salesInventories.add(salesInventoryEntity);
}
salesInventoryRepository.saveAll(salesInventories);
}
After init my base data, I used jooq to read the data, and find nothing. I don't know whether jooq can't read other transaction's data or jooq just read the actual data from the database. If you know something about it please give me some advices.
We use the TFS Java API to fetch WorkItems from a TFS server:
TFSTeamProjectCollection collection = TFSTeamProjectCollectionUtils
.openTeamProjectCollection(serverUrl, credentials,
new DefaultConnectionAdvisor(Locale.getDefault(),
TimeZone.getDefault()));
WorkItemClient client = collection.getWorkItemClient();
List<WorkItem> result = new ArrayList<>();
try {
WorkItemCollection workItems = client.query(wiqlQuery, null, false);
for (int i = 0; i < workItems.size(); i++) {
WorkItem item = workItems.getWorkItem(i);
result.add(item);
}
return result;
} catch (TECoreException e) {
throw new ConQATException("Failed to fetch work items from TFS", e);
}
If I run the query select * from workitems I get all workitems on the server with all fields and all links. Since I'm only interested in some of the fields, I would like to restrict the query to only those and save some bandwidth/time: select ID, Title from workitems
This works fine, but now the links of the items are missing (i.e. item.getLinks() always returns an empty collection).
Is there a way to select the links other than select * from workitems?
After some more digging around, I found that you can create a link query and run it like this:
WorkItemLinkInfo[] infos = client.createQuery("select * from workitemlinks").runLinkQuery()
With this, you can get the links as WorkItemLinkInfo objects that contain the IDs of the target and source node and the link type.
The solution using WorkItemLinkInfo is correct.
Just as remark: Using a WIQL Query you only receive the attributes you were querying - which cannot be the set of links of a work item (therefore always empty). If you query a single workitem using
WorkItemClient client = TFSConnection.getClient();
WorkItem firstWorkItem = client.getWorkItemByID(id);
then you also get the LinkCollection using (containing RelatedLinks, ExternalLinks or HyperLinks)
LinkCollection linkcoll = firstWorkItem.getLinks()
I have an application which requests the Google App Engine Java server
and fetch 15 records per call. I have a big database so I am using
Cursor technique to get only 15 records from database at one time.
The issue is that I have a column “Detail” on datastore which has on
average 1000 characters per record. The client end of my application
sends a keyword e.g. software, to server end and the server end has to
check if that keyword exists in “Detail” column and if it does then
return 15 records which have this keyword. How can I add this filter
in my code?
int pageSize = 15;
FetchOptions fetchOptions = FetchOptions.Builder.withLimit(pageSize);
String startCursor = req.getParameter("cursor");
// If this servlet is passed a cursor parameter, let's use it
if (startCursor != null) {
fetchOptions.startCursor(Cursor.fromWebSafeString(startCursor));
}
Query q = new Query("Table").addSort("dateAdded", SortDirection.DESCENDING);
PreparedQuery pq = datastore.prepare(q);
QueryResultList<Entity> results = pq.asQueryResultList(fetchOptions);
for (Entity entity : results) {
entity.getProperty("dateAdded");
}
You have to use the Search API to index your "Detail" property.
I'm trying to search tweets using search method in twitter4j. My code is as
follows,
public List<Tweet> searchTweets(Query searchQuery) {
QueryResult queryResult = twitter.search(searchQuery);
return queryResult != null ? queryResult.getTweets() : new
ArrayList<Tweet>(0);
}
How do I exclude retweets from my search query results
I was looking for how to exclude the replies on the query search, so I found this topic.
To exclude retweets, this worked well for me:
Query query = new Query("from:"+twitterAccount + " +exclude:retweets");
I would rather comment on this but I can't yet so I'll post this as an answer. You need to edit the Query by appending parameters to it. The source code for Query.java can be found in the examples folder in the twitter4j folder.
public Query(String query) {
this.query = query;
}
Check out Twitter search (atom) API - exclude retweets. The search basis is different but the concept is the same, which is appending +exclude:retweets to the end of your string query. Try it out and do let me know if it works!
Query query = new Query(yourQuery + " -filter:retweets");
source
PS. I don't know the difference betweeen +exclude:retweets and -filter:retweets; both seem to do the job similarly.
I used a different approach than above. See my code below:
List<Status> tweets = result.getTweets();
for (Status tweet : tweets )
{
if( !tweet.isRetweet() )
// processing ....
}
It works for me. However, there might be efficiency differences between these approaches.
You can use set in the configuration builder the option setIncludeRTsEnabled to false, so is going to remove the retweets.
ConfigurationBuilder builder = new ConfigurationBuilder();
builder.setIncludeRTsEnabled(false);
Twitter twitter = new TwitterFactory(builder.build()).getInstance();