Je programme une application Android et utilise ormLite pour la base de données.Modèle composite avec OrmLite pour Android
Je souhaite utiliser le Composite Pattern pour certains éléments de base de données.
j'ai écrit le code suivant:
Foodstuff
package com.android.droidfridge.data;
import com.j256.ormlite.field.DatabaseField;
public abstract class Foodstuff
{
@DatabaseField(id = true, useGetSet = true)
private String name;
@DatabaseField(useGetSet = true, foreign = true)
private Category category;
@DatabaseField(useGetSet = true)
private int image;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public Category getCategory()
{
return category;
}
public void setCategory(Category category)
{
this.category = category;
}
public int getImage()
{
return image;
}
public void setImage(int image)
{
this.image = image;
}
}
Ingrédients
package com.android.droidfridge.data;
import java.io.Serializable;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;
@DatabaseTable(tableName = "ingredients")
public class Ingredient extends Foodstuff implements Serializable
{
private static final long serialVersionUID = 5798705059641377421L;
@DatabaseField(useGetSet = true)
private int amount;
@DatabaseField(useGetSet = true)
private int defaultAmount;
@DatabaseField(useGetSet = true)
private float price;
@DatabaseField(useGetSet = true)
private BaseUnit unit;
public float getPrice()
{
return price;
}
public void setPrice(float price)
{
this.price = price;
}
public BaseUnit getUnit()
{
return unit;
}
public void setUnit(BaseUnit unit)
{
this.unit = unit;
}
public int getDefaultAmount()
{
return defaultAmount;
}
public void setDefaultAmount(int defaultAmount)
{
this.defaultAmount = defaultAmount;
}
public int getAmount()
{
return amount;
}
public void setAmount(int amount)
{
this.amount = amount;
}
public void add(int additional)
{
this.amount += additional;
}
public void add_default_amount()
{
this.add(this.defaultAmount);
}
}
Recette
package com.android.droidfridge.data;
import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.field.ForeignCollectionField;
import com.j256.ormlite.table.DatabaseTable;
@DatabaseTable(tableName = "recipes")
public class Recipe extends Foodstuff implements Serializable
{
private static final long serialVersionUID = 635229962897104194L;
@DatabaseField(useGetSet = true)
private int duration;
@ForeignCollectionField(eager = true)
private Collection<Foodstuff> ingredients;
public int getDuration()
{
return duration;
}
public void setDuration(int duration)
{
this.duration = duration;
}
public Collection<Foodstuff> getIngredients()
{
return ingredients;
}
public void setIngredients(Collection<Foodstuff> ingredients) {
this.ingredients = ingredients;
}
public Foodstuff getIngredient(Foodstuff ingredient)
{
if(ingredients.contains(ingredient))
{
Iterator<Foodstuff> iterator = ingredients.iterator();
boolean check = true;
while(check)
{
if(iterator.equals(ingredient))
return (Foodstuff) iterator;
if(iterator.hasNext())
iterator.next();
else
check = false;
}
}
return null;
}
public void addIngredient(Ingredient ingredient)
{
ingredients.add(ingredient);
}
public void removeIngredient(Foodstuff ingredient)
{
ingredients.remove(ingredient);
}
public int sizeOfIngredients()
{
return ingredients.size();
}
}
Catégorie package com.android.droidfridge.data;
import java.io.Serializable;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;
@DatabaseTable(tableName = "categories")
public class Category implements Serializable
{
private static final long serialVersionUID = -2222256865380949570L;
@DatabaseField(id = true, useGetSet = true)
private String name;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
}
Les produits alimentaires peuvent être des ingrédients ou des recettes. Les recettes sont des ingrédients ou d'autres recettes. Chaque ingrédient et recette a une catégorie.
Je sauvegarde chaque catégorie, ingrédient et recette. Mais, quand je commence mon application, le journal montre des erreurs comme suit:
11-23 21:50:16.493: I/TableUtils(261): creating table 'ingredients'
11-23 21:50:16.513: I/TableUtils(261): executed create table statement changed 1 rows: CREATE TABLE `ingredients` (`unit` VARCHAR , `defaultAmount` INTEGER , `price` FLOAT , `amount` INTEGER , `category_id` VARCHAR , `name` VARCHAR , `image` INTEGER , PRIMARY KEY (`name`))
11-23 21:50:16.603: D/dalvikvm(261): GC_FOR_MALLOC freed 8647 objects/515488 bytes in 44ms
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): Unable to create databases, sorry dude!
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): java.sql.SQLException: Foreign collection object class com.android.droidfridge.data.Foodstuff for field 'ingredients' does not contain a foreign field of class class com.android.droidfridge.data.Recipe
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at com.j256.ormlite.field.FieldType.configDaoInformation(FieldType.java:345)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at com.j256.ormlite.dao.BaseDaoImpl.initialize(BaseDaoImpl.java:171)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at com.j256.ormlite.dao.BaseDaoImpl.<init>(BaseDaoImpl.java:118)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at com.j256.ormlite.dao.BaseDaoImpl.<init>(BaseDaoImpl.java:97)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at com.j256.ormlite.dao.BaseDaoImpl$3.<init>(BaseDaoImpl.java:782)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at com.j256.ormlite.dao.BaseDaoImpl.createDao(BaseDaoImpl.java:782)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at com.j256.ormlite.dao.DaoManager.createDao(DaoManager.java:74)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at com.j256.ormlite.table.TableUtils.createTable(TableUtils.java:218)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at com.j256.ormlite.table.TableUtils.createTable(TableUtils.java:53)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at com.android.droidfridge.data.DatabaseHelper.onCreate(DatabaseHelper.java:35)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper.onCreate(OrmLiteSqliteOpenHelper.java:168)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:106)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at com.j256.ormlite.android.AndroidConnectionSource.getReadWriteConnection(AndroidConnectionSource.java:60)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at com.j256.ormlite.dao.BaseDaoImpl.create(BaseDaoImpl.java:286)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at com.android.droidfridge.ListActivity.createIngredient(ListActivity.java:88)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at com.android.droidfridge.ListActivity.onCreate(ListActivity.java:45)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at android.app.ActivityThread.startActivityNow(ActivityThread.java:2503)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at android.app.LocalActivityManager.moveToState(LocalActivityManager.java:127)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at android.app.LocalActivityManager.startActivity(LocalActivityManager.java:339)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at android.widget.TabHost$IntentContentStrategy.getContentView(TabHost.java:651)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at android.widget.TabHost.setCurrentTab(TabHost.java:323)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at android.widget.TabHost$2.onTabSelectionChanged(TabHost.java:129)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at android.widget.TabWidget$TabClickListener.onClick(TabWidget.java:453)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at android.view.View.performClick(View.java:2408)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at android.view.View$PerformClick.run(View.java:8816)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at android.os.Handler.handleCallback(Handler.java:587)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at android.os.Handler.dispatchMessage(Handler.java:92)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at android.os.Looper.loop(Looper.java:123)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at android.app.ActivityThread.main(ActivityThread.java:4627)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at java.lang.reflect.Method.invokeNative(Native Method)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at java.lang.reflect.Method.invoke(Method.java:521)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
11-23 21:50:16.663: E/com.android.droidfridge.data.DatabaseHelper(261): at dalvik.system.NativeStart.main(Native Method)
11-23 21:50:16.843: I/Database(261): sqlite returned: error code = 1, msg = no such table: categories
11-23 21:50:16.843: W/System.err(261): java.sql.SQLException: Unable to run insert stmt on object [email protected]: INSERT INTO `categories` (`name`) VALUES (?)
11-23 21:50:16.853: W/System.err(261): at com.j256.ormlite.misc.SqlExceptionUtil.create(SqlExceptionUtil.java:22)
11-23 21:50:16.853: W/System.err(261): at com.j256.ormlite.stmt.mapped.MappedCreate.insert(MappedCreate.java:117)
11-23 21:50:16.853: W/System.err(261): at com.j256.ormlite.stmt.StatementExecutor.create(StatementExecutor.java:341)
11-23 21:50:16.853: W/System.err(261): at com.j256.ormlite.dao.BaseDaoImpl.create(BaseDaoImpl.java:288)
11-23 21:50:16.853: W/System.err(261): at com.android.droidfridge.ListActivity.createIngredient(ListActivity.java:88)
11-23 21:50:16.853: W/System.err(261): at com.android.droidfridge.ListActivity.onCreate(ListActivity.java:45)
11-23 21:50:16.853: W/System.err(261): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
11-23 21:50:16.853: W/System.err(261): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
11-23 21:50:16.853: W/System.err(261): at android.app.ActivityThread.startActivityNow(ActivityThread.java:2503)
11-23 21:50:16.853: W/System.err(261): at android.app.LocalActivityManager.moveToState(LocalActivityManager.java:127)
11-23 21:50:16.863: W/System.err(261): at android.app.LocalActivityManager.startActivity(LocalActivityManager.java:339)
11-23 21:50:16.863: W/System.err(261): at android.widget.TabHost$IntentContentStrategy.getContentView(TabHost.java:651)
11-23 21:50:16.863: W/System.err(261): at android.widget.TabHost.setCurrentTab(TabHost.java:323)
11-23 21:50:16.863: W/System.err(261): at android.widget.TabHost$2.onTabSelectionChanged(TabHost.java:129)
11-23 21:50:16.863: W/System.err(261): at android.widget.TabWidget$TabClickListener.onClick(TabWidget.java:453)
11-23 21:50:16.863: W/System.err(261): at android.view.View.performClick(View.java:2408)
11-23 21:50:16.863: W/System.err(261): at android.view.View$PerformClick.run(View.java:8816)
11-23 21:50:16.863: W/System.err(261): at android.os.Handler.handleCallback(Handler.java:587)
11-23 21:50:16.863: W/System.err(261): at android.os.Handler.dispatchMessage(Handler.java:92)
11-23 21:50:16.863: W/System.err(261): at android.os.Looper.loop(Looper.java:123)
11-23 21:50:16.863: W/System.err(261): at android.app.ActivityThread.main(ActivityThread.java:4627)
11-23 21:50:16.863: W/System.err(261): at java.lang.reflect.Method.invokeNative(Native Method)
11-23 21:50:16.873: W/System.err(261): at java.lang.reflect.Method.invoke(Method.java:521)
11-23 21:50:16.873: W/System.err(261): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
11-23 21:50:16.873: W/System.err(261): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
11-23 21:50:16.873: W/System.err(261): at dalvik.system.NativeStart.main(Native Method)
11-23 21:50:16.873: W/System.err(261): Caused by: java.sql.SQLException: inserting to database failed: INSERT INTO `categories` (`name`) VALUES (?)
11-23 21:50:16.883: W/System.err(261): at com.j256.ormlite.misc.SqlExceptionUtil.create(SqlExceptionUtil.java:22)
11-23 21:50:16.883: W/System.err(261): at com.j256.ormlite.android.AndroidDatabaseConnection.insert(AndroidDatabaseConnection.java:102)
11-23 21:50:16.883: W/System.err(261): at com.j256.ormlite.stmt.mapped.MappedCreate.insert(MappedCreate.java:72)
11-23 21:50:16.883: W/System.err(261): ... 24 more
11-23 21:50:16.883: W/System.err(261): Caused by: android.database.sqlite.SQLiteException: no such table: categories: , while compiling: INSERT INTO `categories` (`name`) VALUES (?)
11-23 21:50:16.893: W/System.err(261): at android.database.sqlite.SQLiteCompiledSql.native_compile(Native Method)
11-23 21:50:16.893: W/System.err(261): at android.database.sqlite.SQLiteCompiledSql.compile(SQLiteCompiledSql.java:91)
11-23 21:50:16.893: W/System.err(261): at android.database.sqlite.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:64)
11-23 21:50:16.893: W/System.err(261): at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:80)
11-23 21:50:16.903: W/System.err(261): at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:36)
11-23 21:50:16.903: W/System.err(261): at android.database.sqlite.SQLiteDatabase.compileStatement(SQLiteDatabase.java:1145)
11-23 21:50:16.903: W/System.err(261): at com.j256.ormlite.android.AndroidDatabaseConnection.insert(AndroidDatabaseConnection.java:94)
11-23 21:50:16.903: W/System.err(261): ... 25 more
11-23 21:50:16.903: I/Database(261): sqlite returned: error code = 1, msg = no such table: categories
11-23 21:50:16.903: I/Database(261): [ 11-23 21:50:17.044 261:0x105 I/java.sql.SQLException: queryForOne from database failed: SELECT * FROM `categories` WHERE `nObject Error
11-23 21:50:17.044: I/Database(261): sqlite returned: error code = 1, msg = no such table: categories
11-23 21:50:17.044: W/System.err(261): java.sql.SQLException: Unable to run insert stmt on object [email protected]: INSERT INTO `categories` (`name`) VALUES (?)
11-23 21:50:17.053: W/System.err(261): at com.j256.ormlite.misc.SqlExceptionUtil.create(SqlExceptionUtil.java:22)
11-23 21:50:17.053: W/System.err(261): at com.j256.ormlite.stmt.mapped.MappedCreate.insert(MappedCreate.java:117)
11-23 21:50:17.053: W/System.err(261): at com.j256.ormlite.stmt.StatementExecutor.create(StatementExecutor.java:341)
11-23 21:50:17.053: W/System.err(261): at com.j256.ormlite.dao.BaseDaoImpl.create(BaseDaoImpl.java:288)
11-23 21:50:17.053: W/System.err(261): at com.android.droidfridge.ListActivity.createIngredient(ListActivity.java:88)
11-23 21:50:17.053: W/System.err(261): at com.android.droidfridge.ListActivity.onCreate(ListActivity.java:46)
11-23 21:50:17.053: W/System.err(261): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
11-23 21:50:17.053: W/System.err(261): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
11-23 21:50:17.053: W/System.err(261): at android.app.ActivityThread.startActivityNow(ActivityThread.java:2503)
11-23 21:50:17.053: W/System.err(261): at android.app.LocalActivityManager.moveToState(LocalActivityManager.java:127)
11-23 21:50:17.053: W/System.err(261): at android.app.LocalActivityManager.startActivity(LocalActivityManager.java:339)
11-23 21:50:17.053: W/System.err(261): at android.widget.TabHost$IntentContentStrategy.getContentView(TabHost.java:651)
11-23 21:50:17.053: W/System.err(261): at android.widget.TabHost.setCurrentTab(TabHost.java:323)
11-23 21:50:17.053: W/System.err(261): at android.widget.TabHost$2.onTabSelectionChanged(TabHost.java:129)
11-23 21:50:17.053: W/System.err(261): at android.widget.TabWidget$TabClickListener.onClick(TabWidget.java:453)
11-23 21:50:17.053: W/System.err(261): at android.view.View.performClick(View.java:2408)
11-23 21:50:17.053: W/System.err(261): at android.view.View$PerformClick.run(View.java:8816)
11-23 21:50:17.053: W/System.err(261): at android.os.Handler.handleCallback(Handler.java:587)
11-23 21:50:17.053: W/System.err(261): at android.os.Handler.dispatchMessage(Handler.java:92)
11-23 21:50:17.053: W/System.err(261): at android.os.Looper.loop(Looper.java:123)
11-23 21:50:17.053: W/System.err(261): at android.app.ActivityThread.main(ActivityThread.java:4627)
11-23 21:50:17.053: W/System.err(261): at java.lang.reflect.Method.invokeNative(Native Method)
11-23 21:50:17.053: W/System.err(261): at java.lang.reflect.Method.invoke(Method.java:521)
11-23 21:50:17.053: W/System.err(261): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
11-23 21:50:17.053: W/System.err(261): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
11-23 21:50:17.053: W/System.err(261): at dalvik.system.NativeStart.main(Native Method)
11-23 21:50:17.053: W/System.err(261): Caused by: java.sql.SQLException: inserting to database failed: INSERT INTO `categories` (`name`) VALUES (?)
11-23 21:50:17.053: W/System.err(261): at com.j256.ormlite.misc.SqlExceptionUtil.create(SqlExceptionUtil.java:22)
11-23 21:50:17.053: W/System.err(261): at com.j256.ormlite.android.AndroidDatabaseConnection.insert(AndroidDatabaseConnection.java:102)
11-23 21:50:17.053: W/System.err(261): at com.j256.ormlite.stmt.mapped.MappedCreate.insert(MappedCreate.java:72)
11-23 21:50:17.053: W/System.err(261): ... 24 more
11-23 21:50:17.053: W/System.err(261): Caused by: android.database.sqlite.SQLiteException: no such table: categories: , while compiling: INSERT INTO `categories` (`name`) VALUES (?)
11-23 21:50:17.073: W/System.err(261): at android.database.sqlite.SQLiteCompiledSql.native_compile(Native Method)
11-23 21:50:17.073: W/System.err(261): at android.database.sqlite.SQLiteCompiledSql.compile(SQLiteCompiledSql.java:91)
11-23 21:50:17.073: W/System.err(261): at android.database.sqlite.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:64)
11-23 21:50:17.073: W/System.err(261): at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:80)
11-23 21:50:17.073: W/System.err(261): at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:36)
11-23 21:50:17.073: W/System.err(261): at android.database.sqlite.SQLiteDatabase.compileStatement(SQLiteDatabase.java:1145)
11-23 21:50:17.073: W/System.err(261): at com.j256.ormlite.android.AndroidDatabaseConnection.insert(AndroidDatabaseConnection.java:94)
11-23 21:50:17.073: W/System.err(261): ... 25 more
11-23 21:50:17.073: I/Database(261): sqlite returned: error code = 1, msg = no such table: categories
11-23 21:50:17.073: I/Database(261): [ 11-23 21:50:17.083 261:0x105 I/java.sql.SQLException: queryForOne from database failed: SELECT * FROM `categories` WHERE `nObject Error
11-23 21:50:17.083: I/Database(261): sqlite returned: error code = 1, msg = no such table: categories
11-23 21:50:17.083: E/Recipe(261): java.sql.SQLException: queryForOne from database failed: SELECT * FROM `categories` WHERE `name` = ?
Question:
- Pourquoi puis-je pas créer la base de données de catégorie?
- Y a-t-il une erreur dans ma classe de recette dans l'attribut ingredients?