Creating multiple tables using SugarORM gives IllegalStateException - java

I have two classes, Inventory and Recipe. The problem I have is that I cannot add items to the Recipe table. I get the following error message:
java.lang.IllegalStateException:
Caused by: android.database.sqlite.SQLiteException: table RECIPE has no column named NAME (code 1): , while compiling: INSERT OR REPLACE INTO RECIPE(ID,INGREDIENTS,HOW_TO,NAME) VALUES (?,?,?,?)
This happens when I launch the method goToSearchResults(View view), located in MainActivity.
Inventory looks as follows:
import com.orm.SugarRecord;
public class Inventory extends SugarRecord {
String foodType;
String foodName;
String foodQuantity;
public Inventory(){
}
public Inventory(String foodType, String foodName, String foodQuantity) {
this.foodType = foodType;
this.foodName = foodName;
this.foodQuantity = foodQuantity;
}
public String getFoodType() {
return foodType;
}
#Override
public String toString() {
return foodType +
" " + foodName + '\'' +
" " +foodQuantity + '\''
;
}
public void setFoodType(String foodType) {
this.foodType = foodType;
}
public String getFoodQuantity() {
return foodQuantity;
}
public void setFoodQuantity(String foodQuantity) {
this.foodQuantity = foodQuantity;
}
public String getFoodName() {
return foodName;
}
public void setFoodName(String foodName) {
this. foodName = foodName;
}
}
The class Recipe looks as follows.
import com.orm.SugarRecord;
public class Recipe extends SugarRecord {
String name;
String ingredients;
String howTo;
public Recipe() {
}
public Recipe(String name, String ingredients, String howTo) {
this.name = name;
this.ingredients = ingredients;
this.howTo = howTo;
}
public String getIngredients() {
return ingredients;
}
public void setIngredients(String ingredients) {
this.ingredients = ingredients;
}
public String getHowTo() {
return howTo;
}
public void setHowTo(String howTo) {
this.howTo = howTo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public String toString() {
return "Recipe{" +
"name='" + name + '\'' +
", ingredients='" + ingredients + '\'' +
", howTo='" + howTo + '\'' +
'}';
}
}
When I try to add items to the Inventory table, I use the following two lines:
inventory = new Inventory(foodType, foodName.getText().toString(), foodQuantity.getText().toString());
inventory.save();
This works fine. Items are added to Inventory in the way that I want them to.
However, when I try to put items into the Recipe table, using the following two lines (initialized in the main activity). In the main activity, I have a method, which is a dummy method used for debugging purposes.
public void goToSearchResults(View view){
Intent intent = new Intent(this, SearchResults.class);
recipe = new Recipe("Filet Mignon", "Beef, Potatoes", "Use the owen to cook the potatoes real good -_^");
recipe.save();
startActivity(intent);
}
Why doesn’t this work? To me, it seems like the two classes and their usage are identical to each other, and only one works.

Please try my suggestion hope it works :
Update your Sugar to the latest version which is 1.5 here
Try to modify your manifest configure : like modify the name of the database, and correct the location of your class entities. here
I solve my issue following the steps above.

Related

"JSON parse error: Cannot construct instance of (although at least one Creator exists): cannot deserialize from Object value - SpringBoot

I am using SpringBoot with Mongo database and I am trying to save embedded documents into database.
I have this model:
Profile.java
#Data
#Document
public class Profile {
public final City city;
public final String imageId;
public Profile(City city,
String imageId) {
this.city = city;
this.imageId = imageId;
}
#Override
public String toString() {
return "Profile{" +
", city=" + city +
", imageId='" + imageId + '\'' +
'}';
}
private static boolean atLeast(int numChars, String s) {
if (s == null) {
return false;
}
var str = s.strip();
return str.length() >= numChars;
}
public static ProfileBuilder builder() {
return new ProfileBuilder();
}
public static final class ProfileBuilder {
public City city;
public String imageId;
private ProfileBuilder() {
}
public ProfileBuilder withCity(City city) {
this.city = city;
return this;
}
public ProfileBuilder withImageId(String imageId) {
this.imageId = imageId;
return this;
}
public Profile build(){
return new Profile(city, imageId);
}
}
}
City.java
public class City {
public final String name;
public City(String name) {
this.name = name;
}
#Override
public String toString() {
return "City{" +
", name='" + name + '\'' +
'}';
}
}
ProfileController.java
#RequestMapping( method = RequestMethod.POST)
public Profile addUser(#RequestBody Profile profile) {
return profileService.addProfile(profile);
}
and with postman I am sending this JSON
{
"city":{
"name":"Atena"
},
"imageId" : "Doe",
}
}
But I am getting following error:
"JSON parse error: Cannot construct instance of `domain.City` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator);"
There are at least two solutions.
Add #JsonCreator to constructor and #JsonProperty to its arguments (to instruct Jackson how to substitute JSON items into constructor in proper order)
class Profile {
...
#JsonCreator
public Profile(#JsonProperty("city") City city,
#JsonProperty("imageId") String imageId) {
this.city = city;
this.imageId = imageId;
}
...
}
(+ same for City class)
Unfinal class properties and provide default no-arg constructor (along with existing all-arg constructor).
class Profile {
public City city;
public String imageId;
public Profile() {
}
public Profile(City city, String imageId) {
this.city = city;
this.imageId = imageId;
}
}
(+ same for City class)
Test
class Test {
public static void main(String[] args) throws JsonProcessingException {
String json = "{\"city\":{\"name\":\"Atena\"},\"imageId\":\"Doe\"}";
Profile p = new ObjectMapper().readValue(json, Profile.class);
System.out.println(p);
}
}
Output:
Profile{, city=City{, name='Atena'}, imageId='Doe'}
In classes with only one attribute, to deserialize an object Json need a nos argument constructor from that class.
In your class city you need a nos arg constructor add this to your class you need:
public City () {}

Android POJO class check if particular key contains value as Boolean or arraylist

I have JsonArraylist in which there are multiple jsonobjects.In one of jsonObject json key contains Boolean value and on other Jsonobject the same key contain ArrayList.
How to check in POJO class if key contains ArrayList or boolean value as i am getting error:
W/System.err: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BOOLEAN at line 1 column 1927 path $1.tags
The Json is:
My POJO class is :
public class Posts implements Serializable
String id;
String title;
boolean mIsBookmark;
ArrayList<WebTags>tags;
public ArrayList<WebTags> getTags() {
return tags;
}
public void setTags(ArrayList<WebTags> tags) {
this.tags = tags;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public boolean isBookmark() {
return mIsBookmark;
}
public void setBookmark(boolean mIsBookmark) {
this.mIsBookmark = mIsBookmark;
}
#Override
public String toString() {
return "Webapps_post{" +
"id='" + id + '\'' +
", title='" + title + '\'' +
", date='" + date + '\'' +
", tags='"+ tags+'\'' +
'}';
}
public class WebTags implements Serializable
{
String term_id;
String name;
public String getTerm_id() {
return term_id;
}
public void setTerm_id(String term_id) {
this.term_id = term_id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString()
{
return "WebTags{"+
"term_id='" + term_id + '\'' +
", name='" + name + '\'' +
'}';
}}
}
The TypeAdapter is exactly what you are looking for. To summarize you can add a custom conversion logic for a user defined datatype such as a class and the Gson serializer/deserializer is smart enough to do it based on the return type of the conversion methods
An example for the usage can be found here
You would need to create a custom deserializer for class Posts like below:
class PostsDeserializer : JsonDeserializer<Posts> {
#Throws(JsonParseException::class)
override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): Posts {
val finalResult = Posts()
// manually set all elements (except 'tags') to finalResult object.
//...
// set tags element now
val tagsElement = json.asJsonObject.get("tags")
if(tagsElement?.isJsonArray == true) {
finalResult.tags = context.deserialize(tagsElement, WebTags::class.java)
} else {
finalResult.tags = emptyList()
}
return finalResult
}
}
The above code will tell the GSON library what to map when the tags field is an array or when the tags field is a boolean.

(Java) I cannot loop over my arraylist object?

I'm trying to loop over an ArrayList object but I only get the following:
Name & Education:
com.company.Item#69d9c55
I have no clue why this is happening. I'm using the code provided in the MOOC course that I 'm following online, but am trying to redo this in my own small test project as I want to put what I learned into practice.
Here's the code:
Main
package com.company;
import java.util.Scanner;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
// write your code here
Scanner scan = new Scanner(System.in);
ArrayList<Item> itemList = new ArrayList<>();
Item item;
while(true) {
System.out.println("Name plz?");
String name = scan.nextLine();
if (name.isEmpty()) {
break;
}
System.out.println("Education plz?");
String education = scan.nextLine();
if (education.isEmpty()) {
break;
}
item = new Item(name, education);
if (!itemList.contains(item)) {
itemList.add(item);
}
}
System.out.println("Name & Education: ");
for(Item detail : itemList) {
System.out.println(detail);
}
}
}
and the main Class
package com.company;
public class Item {
String name;
String education;
public Item(String name, String education) {
this.name = name;
this.education = education;
}
}
in your for loop you are printing the detail object.
for(Item detail : itemList) {
System.out.println(detail);
}
// prints
com.company.Item#69d9c55
first part is the package name (think folder sort of) and the random number after the # is an hashed value of the object. So basically a sort of short textual representation of the class.
there is two ways of fixing this:
adding getters to the object to fetch the values you want to print:
public class Item {
String name;
String education;
public Item(String name, String education) {
this.name = name;
this.education = education;
}
public String getName() {
return name;
}
public String getEducation() {
return education;
}
}
// Then in your loop fetch the values
for(Item detail : itemList) {
System.out.println(detail.getName());
System.out.println(detail.getEducation());
}
or the slightly more advanced version which is overriding the toString function in the object. Every object has a function called toString which prints per default the object hash. You can customize this by, naming a function toString and then annotation the function with #Override. Then in that function you can write a custom string that you want printed, when you try to print the object.
public class Item {
String name;
String education;
public Item(String name, String education) {
this.name = name;
this.education = education;
}
#Override
public String toString() {
return name + ", " + education;
}
}
in your for-loop while iterating over your Item list (maybe you should redefine your ArrayList using polymorphism) you will be getting each time an object item and not a detail, so choose the name of your execution variable right.
From this object item you should should whether call item.getName() or / and item.getEducation() if you haven't implemented or overriden a public String toString() method for your Item class or #Override public String toString() from the automatic inherited java.lang.Object class.
With that been said, let us fix and optimize your code:
Main.java
package com.company;
import java.util.Scanner;
import java.util.List;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
// write your code here
Scanner scan = new Scanner(System.in);
// Relying on the diamond operator
List<Item> itemList = new ArrayList<>();
Item item;
while(true) {
System.out.println("Name plz?");
String name = scan.nextLine();
if (name.isEmpty()) {
break;
}
System.out.println("Education plz?");
String education = scan.nextLine();
if (education.isEmpty()) {
break;
}
item = new Item(name, education);
if (!itemList.contains(item)) {
itemList.add(item);
}
}
System.out.println("Name & Education: ");
for(Item item : itemList) {
// Just call toString-method of Item class
System.out.println(item.toString());
}
}
}
Item.java
package com.company;
public class Item {
String name;
String education;
public Item(String name, String education) {
this.name = name;
this.education = education;
}
public String getName() {
return this.name;
}
public String getEducation() {
return this.education;
}
// you could also add some setters for these attributes if you need some later on
#Override
public String toString() {
return "[Name: " + this.name + ", Education: " + this.education + "]";
}
}
Hopefully, this will help you out. Also make sure you upvote the answer if it brings more details to you!

New to Java, and trying to solve the main part of the exercise for the OldMacdonald Had a Farm song

I am trying to code a song using polymorphism, but I am quite new to Java coding and have a really basic experience. I could use some help with the classes, but my biggest problem is that I do not know how to write the main part of the code, I'd be very grateful if someone could help me with it.
Here is what I have so far
public class OldMacdonald {
public interface Farm{
public String getName();
public String getNoise();
}
class Dog implements Farm{
String name;
String noise;
public Dog(String name, String noise) {
name=name;
noise=noise;
}
public String getName() {
return name;
}
public String getNoise() {
return noise;
}
}
class Cat implements Farm{
String name;
String noise;
public Cat(String name, String noise) {
name=name;
noise=noise;
}
public String getName() {
return name;
}
public String getNoise() {
return noise;
}
}
class Duck implements Farm{
String name;
String noise;
public Duck(String name, String noise) {
name=name;
noise=noise;
}
public String getName() {
return name;
}
public String getNoise() {
return noise;
}
}
class Cow implements Farm{
String name;
String noise;
public Cow(String name, String noise) {
name=name;
noise=noise;
}
public String getName() {
return name;
}
public String getNoise() {
return noise;
}
}
class Pig implements Farm{
String name;
String noise;
public Pig(String name, String noise) {
name=name;
noise=noise;
}
public String getName() {
return name;
}
public String getNoise() {
return noise;
}
}
class Song{
private Farm [] animal = new Farm[5];
Song() {
animal[0] = new Dog("dog", "woof");
animal[1] = new Cat("cat", "meow");
animal[2] = new Duck("duck", "quack");
animal[3] = new Cow("cow", "moo");
animal[4] = new Pig("pig", "oink");
}
public void lyrics() {
int i;
for(i=0; i<animal.length; i++) {
System.out.println("Old MacDonald had a farm, E I E I O,\r\n" +
"And on his farm he had a " + animal[i].getName() + ", E I E I O.\r\n" +
"With a " + animal[i].getNoise() + " " + animal[i].getNoise() + " here and a " + animal[i].getNoise() + " " + animal[i].getNoise() + " there,\r\n" +
"Here a " + animal[i].getNoise() + ", there a " + animal[i].getNoise() + ", evrywhere a " + animal[i].getNoise() + " " + animal[i].getNoise() + ".\r\n" +
"Old MacDonald had a farm, E I E I O.\r\n\r\n");
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
You need to "launch" your code somehow, in a Java standalone program like this that would be done from the main method:
public static void main(String[] args)
It looks like Song is your class that actually starts everything off so you need to create an instance of that:
public static void main(String[] args) {
Song mySong = new Song();
}
The lyrics are output by the lyrics() method, so we need to call that:
public static void main(String[] args) {
Song mySong = new Song();
mySong.lyrics();
}
You'll want to tweak your Song() constructor method too:
public Song() {
You might want to update your constructors in animal classes too, you were assigning the parameter to itself (easily done when using same names for variables in params and private fields):
public Cat(String name, String noise) {
this.name = name;
this.noise = noise;
}
If I understood you correctly, in your main()method you just have to create an instance of Song and call lyrics() on it, no? That will populate the Farm array with the animals and call the appropriate methods when printing the lyrics.

Printing multiple objects in different classes

The details in this example isn't that important just trying to figure out how I can solve this, I have 3 separate classes Person , Interests and Location. all are objects, a person would have an list of interests and each interest will have a list of locations, i'm using a toString to print my person object and the interest but I can't figure out how to print out the locations of each interest. Do i need to overload my toString?
public class Person{
private String name;
private ArrayList<Interest> interests = new ArrayList<Interest>();
public Person(String name, ArrayList<Interest> interests) {
this.name = name;
this.interests = interests;
}
public void addInterest(Interest newInterest) {
interests.add(newInterest);
}
public Interest getInterest(int indexOfInterest) {
return interests.get(indexOfInterest);
}
public ArrayList<Interest> getInterests() {
return interests;
}
public String getName() {
return name;
}
public String toString() {
String result = getName() + " ";
for(Interest interest : interests) {
result += interest.getName() + "(" + interest.getDangerRating() + ")" + " ";
}
return result.trim();
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public class Interest {
private int dangerRating;
private String name;
private ArrayList<Location> location = new ArrayList<Location>();
public Interest (int dangerRating, String name, ArrayList<Location> location) {
this.dangerRating = dangerRating;
this.name = name;
this.location = location;
}
public int getDangerRating() {
return dangerRating;
}
public String getName() {
return name;
}
}
////////////////////////////////////////////////////////////////
public class Location {
private String location;
public Location (String location){
this.location = location;
}
public String getLocation() {
return location;
}
}
I reccomend making a toString for each class. That way you can call a Location toString in the Intrest's toString, then the location toString in the Person. Also, the ArrayList class has its own toString that prints all the items in the array.
Currently you only have one toString and you are manualy getting the data for each. So for example:
(In the Location Class):
#Override
public String toString()
{
return "Location: " + location;
}
(In the Interest Class):
#Override
public String toString()
{
return "Danger Rating: " + dangerRating +
"Name: " + name +
"Location: " location.toString(); //Note, the name location is confusing here since it is an ARRAYLIST of locations.
}
(In the Person Class):
#Override
public String toString()
{
return "Name: " + name +
"Intrests: " + intrests.toString();
}
(In the Main Class):
public static void main(String[] args)
{
Intrest[] intrests = new Intrest[4]; //TODO: Create intrests, currently they are all null.
Person thePerson = new Person("Eddie", intrests);
System.out.println("Person Info: " + thePerson.toString());
}
Learn to use your tools: every IDE can generate an overriden toString() method and they are good for the most cases.
public class Location {
// ...
#Override
public String toString() {
return "Location{" +
"location='" + location + '\'' +
'}';
}
}
public class Interest {
// ...
#Override
public String toString() {
return "Interest{" +
"dangerRating=" + dangerRating +
", name='" + name + '\'' +
", location=" + location +
'}';
}
}
class Person{
// ...
#Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", interests=" + interests +
'}';
}
}
I would advise you to stick to your IDE's default toString()s, because that will make your toString()'s look consistent acros all your projects, and soon they will be familiar for you and easy to read.
In your Person class, you call interest.toString() in a loop for all interests
public String toString() {
String result = getName() + " ";
for(Interest interest : interests) {
// add this function to print interest stuff
result += interest.toString();
}
return result.trim();
}
In your Interest class, you'll want a toString or similar method like so
public String toString(){
String s = "";
//print stuff for interest i.e. s+= what you want to add
//loop through locations associated with Interest
for(Location l : this.location ){
// print what you want in location.toString()
// add this funciton to your Location class
s += l.toString()
}
return s;
}
And then in your Main you just need to call
person.toString() and it will loop through and print everything for you.

Categories

Resources