Maximum view state size limit (135KB) exceeded - salesforce

This code has been working fine for years.
public PageReference chkinst() {
i=0;
integer j=0;
Set<String> aSearchSet = new Set<String>();
List<Lead> lList = ui;
for (Lead l : lList) {
aSearchSet.add(l.company);
}
Account[] accountToCreate = new Account[]{};
Map<String,Account> companyToAccountMap = new Map<String,Account> ();
for (Account a: [select id, Name from Account where name IN :aSearchSet])
companyToAccountMap.put(a.name,a);
for (Lead l : lList) {
if (!companyToAccountMap.containsKey(l.company)){
Account act = new Account(Name = l.Company , Country__c = l.Country__c );
accountToCreate.add(act);
j = j +1;
}
}
insert accountToCreate;
if(j == 0) {
ApexPages.addMessage(new ApexPages.message(ApexPages.severity.INFO,'All leads have correct institution names'));
} else{
ApexPages.addMessage(new ApexPages.message(ApexPages.severity.INFO,j + ' Institutions created'));
}
return null;
}
Today, it gave me the following error:
Maximum view state size limit (135KB) exceeded. Actual view state size for this page was 135.078KB
Does anyone know why?
Thanks,

It's hard to tell from this code snippet. But if I had to guess. It looks like your companyToAccountMap is a class level variable, and it's probably returning more records now then it used to. If you don't need that map anywhere else in the controller, I would move it to a method level or make it transient.

Related

Attempt to de reference a null object error

On line acct.AmountX__c += amtX this and acct.AmountY__c += amtY this it is giving me an error. The trigger is on after insert and after update. When i am inserting any record in contact then it is giving me an error i don't know why. Why should 'acct' be initialized if i am not wrong this error comes when you have not initialized something.
public class ContactAccountRollUpAmount {
public static void onAfterInsertOrUpdate(List<Contact> cont){
contAccRollUpAmount(cont);
}
public static void contAccRollUpAmount(List<Contact> contactList){
List<Contact> cont = new List<Contact>([Select AccountId, Amount_Type__c, Amount__c
from Contact
where id in: contactList]);
List<Account> accList = new List<Account>([Select id, AmountX__c, AmountY__c
from Account Limit 50000]);
List<Account> accListToUpdate = new List<Account>();
for(Account acct: accList){
Double amtX = 0;
Double amtY = 0;
system.debug('#########'+acct);
for(Contact con: cont){
if(con.AccountId == acct.Id){
if(con.Amount__c != NULL){
if(con.Amount_Type__c == 'AmountX'){
amtX = amtX + con.Amount__c;
} else if(con.Amount_Type__c == 'AmountY'){
amtY = amtY + con.Amount__c;
}
}
}
}
if(amtX != NULL){
acct.AmountX__c += amtX;
}
if(amtY != NULL){
acct.AmountY__c += amtY;
}
accListToUpdate.add(acct);
}
if(accListToUpdate.size()>0){
update accListToUpdate;
}
}
}
The problem is not that the 'acct' is not initialized, its the field 'AmountX__c' and 'AmountY__c'.
As I can see you have queried max of 50000 records, out of these records some of them have 'Null' values for the above two fields.
I suggest please check whether the above two fields have 'Null' values for some records or not.

List has no rows for assignment

Can any one help me in solving this error:List has no rows for assignment to SObject
Class at line :
        
qName = [select Row_Id__c, Name from Ccon__c where Id = :ApexPages.currentPage().getParameters().get('id')].Row_Id__c;
Test Class line :
Controller  controller1  = new Controller(sc1);
This mean your query is returning no result (So the list is empty and then when casting into an Sobject there is not item to take).
qName = [select Row_Id__c, Name from Ccon__c where Id = :ApexPages.currentPage().getParameters().get('id')].Row_Id__c;
I would do it this way (to make sure in any case I will get value from my query if my ID is valid):
Id tempID = null;
if(ApexPages.currentPage().getParameters().get('id') != null)
{
tempId = ApexPages.currentPage().getParameters().get('id');
}
else{ //Error management
}
List<Ccon__c> recordsToProcess = new List<Ccon__c>();
if(tempID != null)
{
recordsToProcess = [select Row_Id__c, Name from Ccon__c where Id = :tempID];
}
else{ //Error management
}
//qName Declaration
if(!recordsToProcess.isEmpty())
{
qName = recordsToProcess[0].Row_Id__c;
}
else{ //Error management
}
if(qName == null)
{
//Error management
}
If you have more questions please feel free to ask. But as a best practice you might always ensure that your list is not empty before getting the record returned.
Thanks
HqSeO

GAE, Local datastore does not create

I have no idea in what extend GAE is not easy to understand :(
My servlet manipulate a json string and then I'm trying to store it in datastore.
When I run the application I'm getting this output:
Jan 27, 2014 6:59:04 PM com.google.appengine.api.datastore.dev.LocalDatastoreService load
INFO: The backing store, D:\Android\IntelliJ IDEA\workspace\EyeBall\AppEngine\out\artifacts\AppEngine_war_exploded\WEB-INF\appengine-generated\local_db.bin, does not exist. It will be created.
1
2
3
4
5
7
***
***
***
***
***
8
9
Although it's mentioned that local_db.bin will be created but when I navigate to that directory the file is not there. Also, when I open http://localhost:8080/_ah/admin/datastore in browser nothing displays in Entity Kind drop down list.
So wtf happene to local_db.bin? Why it doesn't generates?
any suggestion would be appreciated. thanks.
==================
UPDATE:
I added my code based on request.
private static final String NO_DEVICE_ID = "FFFF0000";
private static final String SAMPLE_JSON = "{\"history\":[{\"date\":null,\"info\":null,\"title\":\"Maybank2u.com\",\"url\":\"https://www.maybank2u.com.my/mbb/Mobile/info.do\",\"visits\":14},{\"date\":null,\"info\":null,\"title\":\"Maybank2u.com\",\"url\":\"https://www.maybank2u.com.my/mbb/Mobile/adaptInfo.do\",\"visits\":4},{\"date\":null,\"info\":null,\"title\":\"Maybank2u.com\",\"url\":\"http://www.maybank2u.com.my/mbb_info/m2u/public/personalBanking.do\",\"visits\":16},{\"date\":null,\"info\":null,\"title\":\"Maybank2u.com Online Financial Services\",\"url\":\"https://www.maybank2u.com.my/mbb/m2u/common/M2ULogin.do?action=Login\",\"visits\":52},{\"date\":null,\"info\":null,\"title\":\"‭BBC\",\"url\":\"http://www.bbc.co.uk/persian/\",\"visits\":16}]}";
private static final String QUERY_HISTORY_DEVICE = "SELECT m FROM HistoryDeviceJPA m WHERE m.userUUID = :keyword ORDER BY m.domain ASC";
private static final String QUERY_HISTORY = "SELECT m FROM HistoryJPA m WHERE m.pageAddress = :keyword";
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// displayError(response, "The page doesn't support httpGet");
String deviceId = NO_DEVICE_ID;
String content = SAMPLE_JSON;
System.out.println("1");
HistoryBrowser historyBrowser = parseJson(content);
if(historyBrowser == null)
return;
System.out.println("2");
List<HistoryBrowser.BrowserInfo> historyList = historyBrowser.getHistory();
if(historyList == null)
return;
System.out.println("3");
List<HistoryDeviceJPA> historyDeviceJPAList = new ArrayList<HistoryDeviceJPA>(historyList.size());
for(int i=0; i<historyList.size(); i++) {
try {
HistoryBrowser.BrowserInfo browser = historyList.get(i);
HistoryDeviceJPA historyDeviceJPA = new HistoryDeviceJPA();
historyDeviceJPA.setUserUUID(deviceId);
historyDeviceJPA.setDomain(getDomainName(browser.getUrl()));
historyDeviceJPA.setPageAddress(browser.getUrl());
historyDeviceJPA.setPageTitle(browser.getTitle());
historyDeviceJPA.setPageVisits(browser.getVisits());
historyDeviceJPAList.add(historyDeviceJPA);
} catch (URISyntaxException e) {
System.out.println(e.getMessage());
}
}
System.out.println("4");
// get history of device from data store
EntityManager em = EMF.get().createEntityManager();
Query q = em.createQuery(QUERY_HISTORY_DEVICE).setParameter("keyword", deviceId);
#SuppressWarnings("unchecked")
List<HistoryDeviceJPA> dbList = (List<HistoryDeviceJPA>) q.getResultList();
System.out.println("5");
// If there is no result (shows there is no record for that device)
if(dbList == null)
addHistoryDeviceJPAToDs(historyDeviceJPAList);
else {
System.out.println("7");
// find each item in datastore and replace them if needed
// if current page visit is less ot equal than previous visit don't do anything (remove item form historyDeviceJPAList)
outerLoop:
for(int i=0; i<historyDeviceJPAList.size(); i++) {
HistoryDeviceJPA deviceItem = historyDeviceJPAList.get(i);
System.out.println("***");
for(int j=0; j<dbList.size(); j++) {
HistoryDeviceJPA dbItem = dbList.get(j);
if(deviceItem.getPageAddress().equalsIgnoreCase(dbItem.getPageAddress())) {
if(deviceItem.getPageVisits() > dbItem.getPageVisits()) {
long diff = deviceItem.getPageVisits() - dbItem.getPageVisits();
dbItem.setPageVisits(deviceItem.getPageVisits());
HistoryJPA historyJPA = findHistoryJPA(dbItem.getPageAddress());
historyJPA.setPageVisits(historyJPA.getPageVisits() + diff);
// update datastore
addHistoryDeviceJPAToDs(dbItem);
addHistoryJPAToDs(historyJPA);
// don't check other items of j list
break outerLoop;
}
}
}
}
System.out.println("8");
}
System.out.println("9");
// http://www.sohailaziz.com/2012/06/scheduling-activities-services-and.html
// https://dev.twitter.com/docs/api/1.1
// https://developers.google.com/appengine/docs/java/datastore/jdo/creatinggettinganddeletingdata?csw=1#Updating_an_Object
// http://en.wikibooks.org/wiki/Java_Persistence/Inheritance
}
and 6 is here:
private void addHistoryDeviceJPAToDs(List<HistoryDeviceJPA> list) {
System.out.println("6");
EntityManager em = EMF.get().createEntityManager();
try {
for (int i=0; i<list.size(); i++) {
System.out.println("=> " + i + " - " + list.get(i).toString());
em.getTransaction().begin();
em.persist(list.get(i));
em.getTransaction().commit();
}
} finally {
em.close();
}
}
after debug I found the problem is in this line:
List<HistoryDeviceJPA> dbList = (List<HistoryDeviceJPA>) q.getResultList();
if(dbList == null)
addHistoryDeviceJPAToDs(historyDeviceJPAList);
'dbList' is never null and it's size is 0 if there is nothing in datastore. That's why addHistoryDeviceJPAToDs method never invoked. By changing the code to following problem solved and local db created.
List<HistoryDeviceJPA> dbList = (List<HistoryDeviceJPA>) q.getResultList();
if(dbList == null)
return;
System.out.println("5");
// If there is no result (shows there is no record for that device)
if(dbList.size() == 0)
addHistoryDeviceJPAToDs(historyDeviceJPAList);
For other people who come across the same issue --
GAE will not create local_db.bin until you put data in the datastore. So if the file is not there, there is likely a bug in the application code.

User Rate Limit Exceeded Exception in Admin SDK

I am working with Admin SDK .when I update single user it's working fine but when I am trying to update bunch(1000) of users I got User Rate Limit Exceeded Exception. Please check below my code and tell me what am i missing ? or tell any suggestion ?
private Directory getDirectoryService(String adminEmailAddress){
Directory directoryService = null;
try {
Collection<String> SCOPES = new ArrayList<String>();
SCOPES.add("https://www.googleapis.com/auth/admin.directory.user");
SCOPES.add("https://www.googleapis.com/auth/admin.directory.user.readonly");
SCOPES.add("https://www.googleapis.com/auth/admin.directory.group");
SCOPES.add("https://www.googleapis.com/auth/admin.directory.group.readonly");
SCOPES.add("https://www.googleapis.com/auth/admin.directory.orgunit");
SCOPES.add("https://www.googleapis.com/auth/admin.directory.orgunit.readonly");
SCOPES.add("https://www.googleapis.com/auth/userinfo.profile");
HttpTransport httpTransport = new NetHttpTransport();
JacksonFactory jsonFactory = new JacksonFactory();
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
.setServiceAccountScopes(SCOPES)
.setServiceAccountUser(adminEmailAddress)
.setServiceAccountPrivateKeyFromP12File(new java.io.File(SERVICE_ACCOUNT_PKCS12_FILE_PATH)).build();
directoryService = new Directory.Builder(httpTransport,jsonFactory, credential).setApplicationName("gdirectoryspring").build();
} catch(Exception e){
ErrorHandler.errorHandler(this.getClass().getName(), e);
}
return directoryService;
}
Below is Update User Code
Directory directoryService = getDirectoryService("adminEmailAddress");
User user = directoryService.users().get("userPrimaryEmail").execute();
List<UserOrganization> organizaionList = user.getOrganizations();
for (int j = 0; j < organizaionList.size(); j++)
{
UserOrganization singleOrg = organizaionList.get(j);
if (singleOrg != null)
{
if ("work".equalsIgnoreCase(singleOrg.getCustomType()) ||singleOrg.getPrimary() != null)
{
if (singleOrg.getTitle() != null)
{
singleOrg.setTitle(jobTitle);
}
}
}
user.setOrganizations(organizaionList);
}
Update update= directoryService.users().update(primaryEmail, user);
User userUpdated = update.execute();
and in admin console I increased my limit like below
Admin SDK 10.0 requests/second/user
but till I am getting User Rate Limit Exceeded Excepiton. can any one help me?
You are missing exponential backoff.
See here for an example (its for drive but can be adapted)
https://developers.google.com/drive/handle-errors#implementing_exponential_backoff in there you will see how it deals with errors like 'userRateLimitExceeded'

Processing: assign a value to each object in an array?

Sorry this is probably a dumb question. I'm kinda new to coding and I'm using Processing, which is based off Java.
I have an array of 5 rectangle objects in my main program
for (int i = 0; i < portals.length; i++)
{
portals[i] = new Portals();
}
when displayed, I call this method from my Portals class
void display()
{
rectMode(CENTER);
rect(xLoc, yLoc, rad, 30);
}
the xLoc and yLoc are determined randomly. How would you go about assigning a number (like an identity) to each object in the array so that I can refer to that specific rectangles's location and where would I put it in my code?
You can have a filed in the class that makes it identifiable. Like:
public class Portals {
int xLoc;
int yLoc;
String name;
...
public Portals(String name){
this.name = name;
}
public String getName(){
return name;
}
}
Then you can try to access by name in array
for (int i = 0; i < portals.length; i++)
{
portals[i] = new Portals("Name");
}
for (Portals p : portals){
if ("Name".equals(p.getname()) {
// do somthing
}
}
Or you can use a Map. But that may be more advanced than your knowledge, so I won't give code. But that's another suggestion.
Edit: with Map
Map<String, Portals> map = new HashMap<String, Portals>();
Key Value
map.put("nameForPortal", new Portals());
map.put("anotherNameForPortal", new Portals());
// To access the portal, you can get by the key
Portals p = map.get("nameForPortal");

Resources