Hey I am working with nested maps as I was trying to use nested map I initialized this map>>. I need to pass accounts industry at key and need to show number of account and accounts group by industry
I have tried to put value but it is showing null pointer exception
Apex class
public class Map_Practice_Show_Account_industry {
public static void mapindustry(){
Map<String,Map<Integer,List<Account>>> m = new Map<String,Map<Integer,List<Account>>>();
List<Account> lstacc = [SELECT Id, Name, Industry FROM Account WHERE industry != Null ];
for(Account acc : lstacc){
List<Account> lstacc1 = new List<Account>();
lstacc1.add(acc);
if(m.containsKey(acc.Industry)){
m.get(acc.Industry).put(m.get(acc.Industry).size(),lstacc1);
} else {
Map<Integer, List<Account>> macc=new Map<Integer, List<Account>>();
macc.put(m.get(acc.Industry).size(),new List<Account>{acc});
m.put(acc.Industry, macc);
}
}
System.debug('#### : '+ m.get('Agriculture'));
}
}
I need to show result like agriculture as a key and at integer 2 and its accounts name
Your error is in second line of you else part (follow pointer for error)
public class Map_Practice_Show_Account_industry {
public static void mapindustry(){
Map<String,Map<Integer,List<Account>>> m = new Map<String,Map<Integer,List<Account>>>();
List<Account> lstacc = [SELECT Id, Name, Industry FROM Account WHERE industry != Null ];
for(Account acc : lstacc){
List<Account> lstacc1 = new List<Account>();
lstacc1.add(acc);
if(m.containsKey(acc.Industry)){
m.get(acc.Industry).put(m.get(acc.Industry).size(),lstacc1);
} else {
Map<Integer, List<Account>> macc=new Map<Integer, List<Account>>();
-->macc.put(m.get(acc.Industry).size(),new List<Account>{acc});
m.put(acc.Industry, macc);
}
}
System.debug('#### : '+ m.get('Agriculture'));
}
}
In if part you are checking if your map contains key acc.Industry but in else part you are still trying to access it even when it's not present in map, it is returning null as a result. Calling size() method on a null object will lead to Null Pointer exception.
Edit:-
then what would be the solution to get the desire result as i am not
able to get size of no of account
I think you have unnecessarily complicated this code. From what I understand from your problem statement, you only need a Map<String, List<Account>> with industry as key and related list of accounts as value. You can get size of accounts for particular industry by fetching list of accounts for that industry and then calling size method on that list. Here is code for this scenario
public class AccountUtils {
//Get all accounts with Industry as key and List of Accounts as Value
public static Map<String,List<Account>> getAccountsGroupedByIndustryMap(){
Map<String,List<Account>> accountsGroupedByIndustry = new Map<String,List<Account>>();
//Fetch all accounts with Industry
List<Account> accountsWithIndustry = [SELECT Id, Name, Industry FROM Account WHERE Industry <> NULL];
for(Account acc : accountsWithIndustry){
List<Account> accountList;
//Check if map already contains current Industry as key
if(accountsGroupedByIndustry.containsKey(acc.Industry)){
//Fetch existing list, add new value and put it back in map
accountList = accountsGroupedByIndustry.get(acc.Industry);
accountList.add(acc);
} else {//If key doesn't exist, create a new list and add account value
accountList = new List<Account>();
accountList.add(acc);
}
//Finally put this list in the map with Industry as key
accountsGroupedByIndustry.put(acc.Industry,accountList);
}
return accountsGroupedByIndustry;
}
}
Posting this from my cellphone not sure how formatting will look like if someone can edit :)
Like pointed above your error is in your second line of the else statement. You are trying to get the size that the industry key is pointing at BEFORE the industry type is inserted to map. Getting non existing keys returns a null and you're trying to get the size() of the null.
So to anwer you're question: Just hardcode the key as ZERO since it's the first elemnent.
Before
macc.put(m.get(acc.Industry).size(),new List<Account>{acc});
After
macc.put(0,new List<Account>{acc});
Related
I am having 1 list of custom objects (around 20,000 or 30,000 records),
-> I need to compare its records to subsequent records based on 3 parameters(type, name and country )and
-> if any records find equal, i have to check date for these two records
-> and only have to keep record with recent date as validated status and marking other record with old status.
Note- max one record can be equal to one record / at a time not 3 or more records can be equal
Right now, I am using ArrayList , implemented equals method in domain class based on 3 parameter. Checking each record to other records and if found equal
-> doing date check and marking their status accordingly and breaking from look and continuing with other records
-> At the end removing all d records with status 'Old'
Can we achieve it in java 8 or other APIs like Apache commons, in effective way?
Code snippet-
`public class Domain implements Comparable<Domain> {
private String type;
private String name;
private String country;
private Date vaildDate;
private String staus;
getter setter
equals method based on type, name , country
public int compareTo(Domain domain) {
return (this.vaildDate).compareTo(domain.getVaildDate());
}
}
In Spring service class
public void saveValidatedRecords() throws IOException {
List<Domain> validatedRecordsInFile = processExternalFTPFile();
List<Domain> dbRecords = dao.findRec(Integer id);
//i have to compare db rec and file records and process according to my question , i am merging both list and processing
List<Domain> listToBeSaved = new ArrayList<Domain>(dbRecords.size()+validatedRecordsInFile.size());
listToBeSaved.addAll(validatedRecordsInFile);
listToBeSaved.addAll(dbRecords);
for (int i= 0; i< listToBeSaved.size(); i++) {
for (int j= i+1;j< listToBeSaved.size() ;j++) {
if (listToBeSaved.get(i).equals(listToBeSaved.get(j)) ) {
if(listToBeSaved.get(i).getValidDate().after(listToBeSaved.get(j).getValidDate()) {
listToBeSaved.get(i).getStatus("Valid");
listToBeSaved.get(j).getStatus("Old");
break; //since only one record will be equal and control goes to outer for
}
}
}
}`
I can use 2 list also here, no need to merge.
Thanks
I need some clarity about session and how to add objects, because I think I do it the wrong way.
First I create a session to hold a list of Products:
Session["ShoppingCart"] = new List<Products>();
To add Products to the list, I do like this:
Session["ShoppingCart"] = new Products { ID = productId, Name = name };
I guess this isn't the right way?
I guess this isn't the right way?
Yes, this isn't the right way (please skip towards the last paragraph of my answer to know the correct way - which is not to use ASP.NET session at all). The correct way is to first get the object you stored inside the session by trying it to cast it to the same .NET type yo uhave stored inside the session:
var products = Session["ShoppingCart"] as List<Products>;
and then if this item is not null add the corresponding product to the list. We should of course make the necessary type check that the session actually contained a value with the specified key and that this value is of the expected type:
if (products != null)
{
var product = new Products { ID = productId, Name = name };
products.Add(product);
}
Of course we are using object references here which will only work if you are storing your session in-memory (sessionState mode = InProc) which of course is absolutely a terrible disaster and something you should never do in production. In a production environment you are probably persisting your session in a session server or even SQL server, aren't you? In this case it is more than obvious that working with object references is a recipe for disaster. So in this case once you have added the new product to the session you should of course set back the new list value to the session which will serialize the object instance to the corresponding data store:
if (products != null)
{
var product = new Products { ID = productId, Name = name };
products.Add(product);
Session["ShoppingCart"] = products;
}
Now, after all this being said I must admit that using ASP.NET Session is probably the huge mistake you would ever commit in a real world application. So basically every time you are using Session["xxx"] you are doing it wrong. Simply search the entire solution for the Session keyword and just get rid of it.
In order to add itens to an existing list on the Session, you must first retrieve the list then add the object to it. Here's an example:
Session["ShoppingCart"] = new List<Products>();
List<Products> productsList = (List<Products>)Session["ShoppingCart"];
productsList.add(new Products { ID = productId, Name = name });
Session["ShoppingCart"] = productsList;
I am using spring-mybatis for a Delete query
this is how my calls look like
if(mapper.deleteSomething(id))
{
.....
}
And in my mapper i have
<delete id = "deleteSomething">
delete from table where id = #{id}
</delete>
However I noticed that return type is not always true in case of successful deletion. Sometimes it returns true and sometimes false, But the records are always deleted in db.
What am I doing wrong?
Here is changes you need to make.
Change the mapper interface method
public interface yourinterface{
public int deleteSomething(<data type> id)
}
I see in your mapper file there is no parameter type mentioned for input, its better to add
Change if condition
int count =mapper.deleteSomething(id);
if(count>0){
System.out.println("Deleted "+ count +"records");
}else{
System.out.println("Delete failed");
}
i want to make sure all product names are unique so i tried to do the following.
but it is causing an infinity loop at the lambda expression.
public partial class Product
{
partial void OnProductNameChanging(string value)
{
using(var ctx = new MyEntityContext()){
var val = value;
var item = ctx.Products.Where(o=>o.ProductName == val).FirstOrDefault();
if(item != null)
throw new ValidationException("Product Name existed.");
}
}
}
i'm using asp.net 4.0 with dynamic data and entity framework.
Why don't you set it up on database level and handle exeption in case if product name already exists?
I am not too familiar with EF, but you should get the changeset and compare values. That is, for the Product Entity and in the case of the the changeset having an Update, compare the EXISTING value with NEW, and change the new in the case of duplication.
Here's how to get changeSet in EF :
http://davidhayden.com/blog/dave/archive/2005/11/16/2570.aspx
the comparison and value must be called before any context.SubmitChanges();
Hope this helps.
My problem is that I am trying to return a simple query that contains an object Story. The Story object has a UserId in the table which links to aspnet_users' UserId column. I have created a partial class for Story that adds the UserName property since it does not exist in the table itself.
The following query gets all stories; however, a pagination helper takes the query and returns only what's necessary once this is passed back to the controller.
public IQueryable<Story> FindAllStories(){
var stories = (from s in db.Stories
orderby s.DateEntered descending
select new Story
{
Title = s.Title,
StoryContent = s.StoryContent,
DateEntered = s.DateEntered,
DateUpdated = s.DateUpdated,
UserName = s.aspnet_User.UserName
}
);
return stories;
}
When the helper does a .count() on the source it bombs with the following exception:
"Explicit construction of entity type 'MyWebsite.Models.Story' in query is not allowed."
Any ideas? It's not a problem with the helper because I had this working when I simply had the UserName inside the Story table. And on a side note - any book recommendations for getting up to speed on LINQ to SQL? It's really kicking my butt. Thanks.
The problem is precisely what it tells you: you're not allowed to use new Story as the result of your query. Use an anonymous type instead (by omitting Story after new). If you still want Story, you can remap it later in LINQ to Objects:
var stories = from s in db.Stories
orderby s.DateEntered descending
select new
{
Title = s.Title,
StoryContent = s.StoryContent,
DateEntered = s.DateEntered,
DateUpdated = s.DateUpdated,
UserName = s.aspnet_User.UserName
};
stories = from s in stories.AsEnumerable() // L2O
select new Story
{
Title = s.Title,
StoryContent = s.StoryContent,
...
};
If you really need to return an IQueryable from your method and still need the Username of the user you can use DataContext.LoadOptions to eagerload your aspnet_user objects.
See this example.