fetching salesforce object's record count using java - java

I have a Java code using partner API for connecting to Salesforce.
I am trying to get the number of records/rows for my salesforce object. All my tries were unsuccessful.
I went through a sample code that uses AggregateResult class for this purpose.When I try to implement it, the program throws error(Cannot cast from SObject to AggregateResult).
How can I do it.

The following may work for you. In my system I have an object Device that is a child of Account. There is also an object Alert that is a child of Device. I used an aggregate query to get the account ids for Alert records that meet a certain condtion.
StringBuilder openAlertQuery = new StringBuilder();
openAlertQuery.append("SELECT Device__r.Account__c");
openAlertQuery.append(" FROM Alert__c WHERE Cleared__c = FALSE GROUP BY Device__r.Account__c");
List<SObject> alertRecords = sfdcServer.doQuery(openAlertQuery.toString());
List<String> accountIds = new ArrayList<String>();
for (SObject alert : alertRecords)
{
String accountId = (String) alert.getChild("Account__c").getValue();
accountIds.add(accountId);
}
Notice the SObject method is getChild(name) rather than the usual getField(name). getChild(name) returns an com.sforce.ws.bind.XmlObject which has the getValue() method.

Related

How can reuse local variable from inside lambda selenium java

The code below was written to capture the session id by going to the Network in selenium. The problem I have is Im not being able to capture the session ID outside of the lambda scope, it's null. However when i log the captured session id from within the lambda, i can actually see the session id printed in the console. Im reading articles saying it's because the variable in lambda are final and etc. but that's not helping me resolve the problem. Im think maybe I could resolve this issue by converting the lambda function to a java for loop (maybe) but im lacking some knowledge there. I'd appreciate if someone could give me a solution for this. To sum, I want to be able to grab that session id, assign it to some kinda variable in the class so I can use it from any method or any class I want for the given test.
static int count = 0;
protected synchronized String getSessionID(){
String[] IDs = new String[1];
DevTools devTools = ((ChromeDriver)Driver.getDriver()).getDevTools();
devTools.createSession();
devTools.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty()));
devTools.addListener(Network.responseReceived(), response -> {
if (count == 0) {
Response responsePayload = response.getResponse();
Optional<Object> optionalSessionID = Optional.ofNullable(responsePayload.getHeaders().get("session-id"));
if (optionalSessionID.isPresent() && !optionalSessionID.get().equals("null")) {
count++;
IDs[0] = optionalSessionID.get().toString();
logger.info("Session ID: " + IDs[0]); // here there's no issue. I see in the session id printed in the console
// THIS IS THE ONLY PLACE WHERE SESSION ID IS AVAILABLE, OUTSIDE FROM HERE, IT's NULL
}
}
});
return IDs[0]; // however it is retuning null at the end.
}

CollectionGroup query in firestore android studio

I am not able enter into for loop. it is not showing any error. when I try to debug it is not entering for loop. after entering into for loop only it can retrieve result. can any one help?
Query query =fstore.collectionGroup("ride").whereEqualTo("from",from1).whereEqualTo("to",to1).whereEqualTo("date",date);
query.get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot snapshots) {
for (QueryDocumentSnapshot queryDocumentSnapshot:snapshots)
{
String source = queryDocumentSnapshot.getString("from");
String destination = ueryDocumentSnapshot.getString("to");
String date1 = queryDocumentSnapshot.getString("date");
String time = queryDocumentSnapshot.getString("time");
String vehicle = queryDocumentSnapshot.getString("vehicle number");
String cost = queryDocumentSnapshot.getString("Cost per person");
String seats = queryDocumentSnapshot.getString("number of seats");
String model = queryDocumentSnapshot.getString("car model");
data += source+" "+destination+" "+date1+" "+time+" "+vehicle+" "+cost+" "+seats+" "+model+"\n";
}
});
enter image description here
In the reference you may find following sentence:
Before using a collection group query, you must create an index that supports your collection group query. You can create an index through an error message, the console, or the Firebase CLI.
From the same reference example it seems that code is done properly. Of course we do not know what do you have in from1, to1 and date variables. From the screenshot it seems that date has strange format in your database. As well I am not sure how it will work with multiple whereEqualTo methods.
So many think could go wrong here, but if I were in your shoes I would start with checking the indexes, and than start from building query with single whereEqualTo trying to get anything from database, exactly like in the reference example.
If you succeed than you can extend it to more sophisticated solutions.
I hope it will help!

How do I minimize object creation in this particular situation?

While implementing a database structure, my goal is to provide easy access to player data.
So, I have created the User class, which holds a Json instance and exposes the methods to take specific information from it.
public class User {
private Json data;
public User(OfflinePlayer player) {
File path = new File(player.getUniqueId() + ".json");
data = new Json(path);
}
public boolean isPremium() {
return data.getBoolean("premium");
}
}
The problem is that I have to create a new instance every time I need to know something about the same player from different parts of my code. That's very expensive!
So, is there a design pattern for this particular situation?
This is a simple cache. If you are using ORM such as hibernate, you could use second level cache for this.
You could also have unique user identifier (UUID id) as a key, with user data as a value in Map.
So, when you get request for user data, you first see if you have user with this uuid in cache(Map) and return data if you do.
If you don't have it, then go in database and fetch data.
Try creating a Map like this:
User user = null;
Map<UUID, User> usermap = new HashMap<>;
//before creating new user instance check if its present in Map
if(usermap.containskey(id){
//get user from Map
user = usermap.get(id);
else{
//not in map so create new User
user = new User(id);
usermap.put(id,user);
}
//use user object
But please be careful to destroy usermap instance or object containing it once it is not required. You can also so several modification with limiting size etc.

Hibernate caches the query while data is being changed

I'm developing an application which connects to an outside service to fetch new SMS. Theses messages are stored in a local database by Hibernate. My client can search these messages based on numerous parameters such as time, number, and etc.
After calling the search method with a list of parameters called 'List1', I get the desired result without any problems. Though while I'm waiting for this result a new message has arrived.
Soon after, I call the search method with same parameter list again and I'm expecting to get the new message as well, but I get the previous result.
I have checked my database and the new message is present so all I can think of is Hibernate caching. Since both queries are exactly the same, I guess hibernate return the same result set as before.
In case my assumption is correct, how can I overcome this problem? If not, so what exactly is going on?
Edit
here is relevant part of my source code. Following two methods will be invoked when client initiates a search request:
smsService.refresh();
JSONArray result = smsService.retrieveMessages(...);
#Transactional
public JSONArray retrieveMessages(Long periodBegining, Long periodEnd, String order, Integer limit, String profile, Boolean unread, String correspondent) {
List<ShortMessage> messageList = shortMessageDAO.find(beginDate, endDate, order, limit, profile, unread, correspondent);
JSONArray result = new JSONArray();
for (ShortMessage message : messageList)
result.put(message.toJSON());
shortMessageDAO.markRead(messageList);
return result;
}
#Transactional
public void refresh() {
webService.authentication(serviceUsername, servicePassword);
while(webService.hasUnread() > 0) {
SMS sms = webService.retrieveMessage();
ShortMessage message = new ShortMessage(sms.getHash(), sms.getFrom(), sms.getTo(), "DEFAULT", sms.getMessage(), new Date(sms.getTime()), true);
shortMessageDAO.insert(message);
}
}
}
public List<ShortMessage> find(Date beginDate, Date endDate, String order, Integer limit, String profile, Boolean unread, String correspondent) {
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(ShortMessage.class);
criteria.add(Restrictions.ge("time", beginDate));
criteria.add(Restrictions.le("time", endDate));
criteria.add(Restrictions.eq("profile", profile));
if (unread)
criteria.add(Restrictions.eq("unread", true));
if (correspondent != null)
criteria.add(Restrictions.eq("origin", correspondent));
criteria.addOrder(order.equals("ASC") ? Order.asc("time") : Order.desc("time"));
criteria.setMaxResults(limit);
criteria.setCacheMode(CacheMode.IGNORE);
return (ArrayList<ShortMessage>) criteria.list();
}
Yes it looks like hibernate is caching your query and returning cached results.
Please give us a overview of your code to suggest better.
Below listed are two ways of controlling the caching behaviour of queries:-
1) At the main named query level:-
#NamedQuery(
name = "myNamedQuery"
query = "SELECT u FROM USER WHERE u.items is EMPTY"
hints = {#QueryHint(name = "org.hibernate.cacheMode", value = "IGNORE")}
)
2) At individual query level :-
Query q = session.createQuery("from User")
.setCacheMode(CacheMode.IGNORE);
After running numerous test, I found out that this problem is not cache related at all. Upon receiving each message I would have stored the time of arrival based on data provided by SMS panel and not my own machine time.
There was a slight time difference (20 seconds to be exact) between those 2 which was the reason behind the query not returning the new received message.

Retrieving multiple values from an arraylist

I have saved values retrieved from a database in java to an arraylist.
I have used a class to save the data to the array list as shown below.
ArrayList<NewSms> details = new ArrayList<NewSms>();
try{
Statement query = conn.createStatement();
ResultSet result = query.executeQuery("Select `senderAddress,message,linkid from sdp_smsincoming where status=0 AND smsServiceActivationNumber =1234 ");`
while(result.next()){
String address = result.getString("senderAddress");
String message = result.getString("message");
String linkid = result.getString("linkid");
NewSms smsdetails = new NewSms();
smsdetails.set_address(address);
smsdetails.set_message(message);
smsdetails.set_linkid(linkid);
details.add(smsdetails);;
}
}
However i now want to retrieve the values individually per row,from another class in the program.How can i do this?By individually i mean getting the address,message and linkid per row in the arraylist.
However i now want to retrieve the values individually per row,from another class in the program.How can i do this?
You just access each NewSms in the list. To access one by index, you could use:
NewSms sms = details.get(2); // Or whatever
// Now access the properties of sms
Or to access each of them in turn, use an enhanced for loop:
for (NewSms sms : details) {
// Now access the properties of sms
}
Note that to comply with Java naming conventions, your NewSms class should have methods such as getAddress, setAddress - not set_address.
Also note that you need to close your result set / statement / connection - if you're using Java 7, you can use a try-with-resources statement; otherwise you should use finally blocks.
EDIT: If your problem is actually just returning the list, that's easy:
public List<NewSms> loadSmsDetails() {
// Code as before...
return details;
}
Then just call it from your other class:
// Where repository is a reference to an instance of the class containing the above method
List<NewSms> allDetails = repository.loadSmsDetails();
for(NewSms smsdetails:details){
String address = smsdetails.get_address();
String message = smsdetails.get_message();
String linkId = smsdetails.get_linkid();
}
However i now want to retrieve the values individually per row,from
another class in the program
You need to pass the arraylist to the another class and iterate over it there to get the individual elements. The idea is to use a common araylist - to store the values from the resultset and in another class to iterate through them.

Categories