I try to integrate Sugar ORM (v 1.3) into my Android application, and when I try to save the newly created object, I continue to crash (NullPointerException).
Here is my accident ...
01-21 06:02:36.012 2856-2856/com.spuddmobile.kel E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: com.spuddmobile.kel, PID: 2856 java.lang.NullPointerException at com.orm.SugarRecord.save(SugarRecord.java:109) at com.orm.SugarRecord.save(SugarRecord.java:45) at com.spuddmobile.kel.Fragments.NewAppFragment._SaveForm(NewAppFragment.java:231) at com.spuddmobile.kel.Fragments.NewAppFragment.onMenuItemSelection(NewAppFragment.java:175) at com.spuddmobile.kel.Activities.MainActivity.onOptionsItemSelected(MainActivity.java:89) at android.app.Activity.onMenuItemSelected(Activity.java:2600) at com.android.internal.policy.impl.PhoneWindow.onMenuItemSelected(PhoneWindow.java:1012) at com.android.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:735) at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:152) at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:874) at com.android.internal.view.menu.ActionMenuView.invokeItem(ActionMenuView.java:546) at com.android.internal.view.menu.ActionMenuItemView.onClick(ActionMenuItemView.java:115) at android.view.View.performClick(View.java:4438) at android.view.View$PerformClick.run(View.java:18422) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5017) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595) at dalvik.system.NativeStart.main(Native Method)
Here is my AppManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.spuddmobile.kel" > <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:name="com.orm.SugarApp" android:theme="@style/AppTheme" > <meta-data android:name="DATABASE" android:value="kel.db" /> <meta-data android:name="VERSION" android:value="1" /> <meta-data android:name="QUERY_LOG" android:value="true" /> <meta-data android:name="DOMAIN_PACKAGE_NAME" android:value="com.spuddmobile.kel.Model" /> <activity android:name=".Activities.MainActivity" android:label="@string/app_name" android:windowSoftInputMode="stateHidden|adjustResize"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <meta-data android:name="android.support.UI_OPTIONS" android:value="splitActionBarWhenNarrow" /> </activity> </application> </manifest>
As you can see, I definitely set android:name to com.orm.SugarApp for documentation.
Here is my entity / domain class ...
public class Appraisal extends SugarRecord<Appraisal> { Double rent; Integer area; Integer currentPeriod; Integer reviewFrequency; Integer rentFreePeriod; Integer interimRentPeriod; Double interimRentPrice; Integer secondInterimRentPeriod; Double secondInterimRentPrice; Double incentives; Integer breakPeriod; Double breakPenalty; Double breakIncentiveRent; Integer breakIncentiveRentPeriod; Double breakRisk; String name; Date createdDate; Date updatedDate; public Appraisal () { } public Appraisal (Double rent, Integer area, Integer currentPeriod, Integer reviewFrequency, Integer rentFreePeriod, Integer interimRentPeriod, Double interimRentPrice, Integer secondInterimRentPeriod, Double secondInterimRentPrice, Double incentives, Integer breakPeriod, Double breakPenalty, Double breakIncentiveRent, Integer breakIncentiveRentPeriod, Double breakRisk, String name, Date createdDate, Date updatedDate) { this.rent = rent; this.area = area; this.currentPeriod = currentPeriod; this.reviewFrequency = reviewFrequency; this.rentFreePeriod = rentFreePeriod; this.interimRentPeriod = interimRentPeriod; this.interimRentPrice = interimRentPrice; this.secondInterimRentPeriod = secondInterimRentPeriod; this.secondInterimRentPrice = secondInterimRentPrice; this.incentives = incentives; this.breakPeriod = breakPeriod; this.breakPenalty = breakPenalty; this.breakIncentiveRent = breakIncentiveRent; this.breakIncentiveRentPeriod = breakIncentiveRentPeriod; this.breakRisk = breakRisk; this.name = name; this.createdDate = createdDate; this.updatedDate = updatedDate; } }
Note that my entity does extend SugarRecord, and I provide the required empty constructor as well as the parameterized constructor. I am NOT redefining the method of superintegration using context, because according to the documentation, which is no longer required in v1.3 Sugar ORM.
Finally, the code crashes ...
// create new app Appraisal nApp = new Appraisal(); nApp.save();
Saving occurs where it fails. Now I checked that the database was created correctly through the Android Device Monitor, and it really exists with the APPRAISAL table. However, when I query the table, it is empty, which makes sense since Sugar never terminates the save() function.
Does anyone know what I'm doing wrong here? To make sure that I have given all the relevant information, below is the Gradle build script.
buildscript { repositories { mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:1.0.0' } } apply plugin: 'android' android { compileSdkVersion 13 buildToolsVersion '19.1.0' defaultConfig { applicationId 'com.spuddmobile.kel' minSdkVersion 13 targetSdkVersion 17 } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' } } productFlavors {} } repositories { mavenCentral() } dependencies { compile 'com.noveogroup.android:android-logger:1.3.4' compile 'com.github.satyan:sugar:1.3' }