Odoo Warning "Perhaps a module was partially removed or renamed" - odoo-9

When I run odoo server, I got this warning message below.
WARNING dietfacts2 openerp.modules.loading: Model product.nutrientitem is declared but cannot be loaded! (Perhaps a module was partially removed or renamed)
I know that it shows this warning message because I created the model name but then I changed it afterward. The model was saved to postgres DB. I tried to delete the table in DB but unsuccessful.
dietfacts2=# delete from ir_model where model = 'product.nutrientitem';
ERROR: null value in column "model" violates not-null constraint
DETAIL: Failing row contains (1011, 2017-02-20 04:15:05.207869, 2017-02-20 04:15:05.207869, 285, null, f, false, product_nutrientitem_write_uid_fkey, null, null, null, null).
CONTEXT: SQL statement "UPDATE ONLY "public"."ir_model_constraint" SET "model" = NULL WHERE $1 OPERATOR(pg_catalog.=) "model""

Likely you have data in other tables that needs to be cleared first. Try ir_model_data
DELETE FROM ir_model_data WHERE model = 'your.model';
Then you should be able to delete your table. If you have constraints related to your table you may need to identify these and remove them as well.

You have stale model data in your db. Usually is due to a model that has been removed/renamed or a module not uninstalled properly.
A useful module to handle these situations:
https://github.com/OCA/server-tools/tree/11.0/database_cleanup
https://www.odoo.com/apps/modules/11.0/database_cleanup/
It allows you to purge stale data for models, actions, etc, whatever "orphan" record is still in your db. You'll find a control panel for database cleanup under technical section.

Related

Laravel Migration - Data type also changes when renaming column

I want to rename the column in database using migration, but when i tried it, the datatype also changes. How to rename column without changing the data type.
The current name of the column in the database is
payment_amount_cash and its type is double(10,2)
I tried
$table->renameColumn('payment_amount_cash', 'payment_amount_full')->comment('Advanced payment')->default("0.00");
to rename the column. Then after migration, the name was changed but the data type was also changed from double(10,2) to only double thus, making the default value change from 0.00 to 0.
I also tried to change the data type after the schema of renaming the column.
$table->renameColumn('payment_amount_cash', 'payment_amount_full')->comment('Advanced payment')->default("0.00");
$table->double('payment_amount_full', 10,2)->change();
but this one gives me error upon migration.
Doctrine\DBAL\DBALException : Unknown column type "double" requested.
Any Doctrine type that you use has to be registered with \Doctrine\DBAL\Types\Type::addType().
You can get a list of all the known types with \Doctrine\DBAL\Types\Type::getTypesMap().
If this error occurs during database introspection then you might have forgotten to register all database types for a Doctrine Type.
Use AbstractPlatform#registerDoctrineTypeMapping() or have your custom types implement Type#getMappedDatabaseTypes().
If the type name is empty you might have a problem with the cache or forgot some mapping information.
With this, I just want to know how to rename the column without affecting the data type. After migration, I would like to retain the data type of the column I just changed the name.
I learned that there is an issue in Schema regarding the enum and still in discussion until now.
I just used the other way to update the datatype of the column.
DB::statement('ALTER TABLE reservations MODIFY COLUMN payment_amount_full double(10,2)');
and this works for me. If there are other ways on how to do this, please let me know. Thanks.

"Failed to add object with ID as the object already exists" but object not visible in playground test environment

I am testing my code on composer-playground. When I try to add a participant through a transaction, I receive an error "Failed to add object with ID --- as the object already exists".
However, when I go to 'test' section, and click the participant type, nothing is listed.
I created a participant with the same ID a few hours ago but it has disappeared after I redeployed my changes. Not sure where it went as it clearly hasn't been deleted.
If you change your model by adding/removing fields that are not optional, or by renaming fields, any existing data that does not match the model 'disappears' from view. However the data is still there and re-appears if you change the model back.
It seems likely that you have changed the model but have residual 'hidden' data and you can't create a new object with the same key you have already used.
This is more fully explained in the Composer Knowledge Wiki.

Model changed during database created

I have uploaded my MVC3 project , it's s simple blog , at first it works well but after couple hours! following error appears (I've made custom error to Off to see the error)
The model backing the 'SiteContext' context has changed since the database was created. Either manually delete/update the database, or call Database.SetInitializer with an IDatabaseInitializer instance. For example, the DropCreateDatabaseIfModelChanges strategy will automatically delete and recreate the database, and optionally seed it with new data.
to solve this I have to manually delete my database and create again and then restore to the backup that I have created. but after after 2 hours again I get the error!
I really don't have any idea , what caused that ??
When you create a model and ask EF to create a database from it, EF would hash the model and store the hash value with the database. Whenever the context is created, EF recomputes the hash and matches it against what is stored at the database. If the model changes in any way, the resulting hash will be different and EF will throw the exception you have just seen. This is done in order to keep the model in sync with the database.
Is there any way the model could have changed during runtime?
One thing you could do to figure out the difference is to
1.Re-create the database from the model as you are doing now and get it scripted (script1.sql).
2.Wait till the error happens and delete the db and re-create it again and script it (script2.sql)
3.Try to compare the two and see whether you can spot a difference in the schemas.
This should give you an idea of what has changed in the model.
Goodluck

Changed existing entity model and manually updated SQL Server database but still get context changed error

I have an existing MVC3 application and database that is on a SQL Server 2008 R2 and I had to add a bool item to an existing model.
After I added it to the model, I rebuilt and published the project. Then I opened up SQL Server Management Studio and went to the table and added the entry to the column as a bit, I had to make it nullable since the table already contains data.
I thought this would be all that I would need to do to get everything working. However I got this error:
The model backing the 'psllc_DB' context has changed since the database was created. Either manually delete/update the database, or call Database.SetInitializer with an IDatabaseInitializer instance. For example, the DropCreateDatabaseIfModelChanges strategy will automatically delete and recreate the database, and optionally seed it with new data.
I'm not sure what else to do, I went back to the code and changed the bool to bool? so it will be nullable but this didn't help either. I can't drop the entire database since it's full of data, however as a last ditch possibility I could drop this table and re-create it cause it only has a few entries, but I don't know if that will work. I'm not sure what else to do so any advice would be very appreciated.
Update
Since I'm not getting any responses, let me rephrase my question.
How should I update my database (a SQL Express mdf file) to add a bool Column to a Table that has data already? I need the database to match my updated MVC 3 Entity Code First model otherwise I get the above error.
Thanks
Since this is code-first, you should do this code-first: change the class and use EF-migrations to change the database. The way you do it, the model and the database may match, but the meta information in the database is not updated.
By the way, if you supply a default value, you can add a non-nullable column.

Using Oracle's GUID()-generated ID's in Grails/Hibernate

I trying to use Grails Scaffolding to throw a quick CRUD application together around some legacy database tables. It is an Oracle database, and the primary key value is intended to be populated by Oracle's GUID() function.
Based on this earlier StackOverflow question, I tried specifying "guid" as the Hibernate generator for this column in my Grails domain class:
...
static mapping = {
table name: "OWNER"
version false
columns {
id column: "OWNER_OID", generator: "guid"
name column: "NAME"
...
}
}
...
When I run my Grails app, viewing and even editing records works just fine. However, when I try to create a new record, things blow up with the Oracle error message "ORA-02289: sequence does not exist".
I enabled SQL logging for my datasource, and see Grails/Hibernate trying to execute the following during a save operation:
select hibernate_sequence.nextval from dual
This doesn't look right at all, and doesn't match the generated SQL from that earlier StackOverflow question linked above. Does anyone see something I am missing here, or otherwise know how to make Grails/Hibernate populate a primary key column with Oracle GUID values?
Whew... after another day of wrestling with this, I think I have my arms around the thing. This answer covers a bit more ground than the original question description, but that's because I found yet more problems after getting past the Hibernate generator issue.
Issue #1: Getting an Oracle GUID() value
As covered by Adam Hawkes' answer, the "guid" Hibernate generator is unmaintained and only works for older versions of the Oracle dialect.
However, if you use the Hibernate generator "assigned" (meaning that you want to set primary keys manually rather than have Hibernate auto-generate them), then you can insert values pulled from an Oracle SYS_GUID() call.
Even though Hibernate's newer Oracle dialects don't support "guid" seamlessly, they still understand the SQL necessary to generate these values. If you are inside of a Controller, you can fetch that SQL query with the following:
String guidSQL = grailsApplication.getMainContext().sessionFactory.getDialect().getSelectGUIDString()
If you are inside of a domain class instead, you can still do this... but you will need to first inject a reference to grailsApplication. You probably want to do this in a Controller, though... more on this below.
If you're curious, the actual String returned here (for Oracle) is:
select rawtohex(sys_guid()) from dual
You can execute this SQL and fetch the generated ID value like this:
String guid = grailsApplication.getMainContext().sessionFactory.currentSession.createSQLQuery(guidSQL).list().get(0)
Issue #2: Actually using this value in a Grails domain object
To actually use this GUID value in your Grails domain class, you need to use the Hibernate generator "assigned". As mentioned earlier, this declares that you want to set your own ID's manually, rather than letting Grails/GORM/Hibernate generate them automatically. Compare this modified code snippet to the one in my original question above:
...
static mapping = {
table name: "OWNER"
version false
id column: "OWNER_OID", generator: "assigned"
name column: "NAME"
...
}
...
In my domain class, I changed "guid" to "assigned". I also found that I needed to eliminate the "columns {}" grouping block, and move all my column information up a level (weird).
Now, in whichever Controller is creating these domain objects... generate a GUID as described above, and plug it into the object's "id" field. In a Controller generated automatically by Grails Scaffolding, the function will be "save()":
def save() {
def ownerInstance = new Owner(params)
String guidSQL = grailsApplication.getMainContext().sessionFactory.getDialect().getSelectGUIDString()
ownerInstance.id = grailsApplication.getMainContext().sessionFactory.currentSession.createSQLQuery(guidSQL).list().get(0)
if (!ownerInstance.save(flush: true, insert: true)) {
render(view: "create", model: [ownerInstance: ownerInstance])
return
}
flash.message = message(code: 'default.created.message', args: [message(code: 'owner.label', default: 'Owner'), ownerInstance.id])
redirect(action: "show", id: ownerInstance.id)
}
You might think to try putting this logic directly inside the domain object, in a "beforeInsert()" function. That would definitely be cleaner and more elegant, but there are some known bugs with Grails that prevent ID's from being set in "beforeInsert()" properly. Sadly, you'll have to keep this logic at the Controller level.
Issue #3: Make Grails/GORM/Hibernate store this properly
The plain truth is that Grails is primarily intended for virgin-new applications, and its support for legacy databases is pretty spotty (in fairness, though, it's a bit less spotty than other "dynamic" frameworks I've tried). Even if you use the "assigned" generator, Grails sometimes gets confused when it goes to persist the domain object.
One such problem is that a ".save()" call sometimes tries to do an UPDATE when it should be doing an INSERT. Notice that in the Controller snippet above, I have added "insert: true" as a parameter to the ".save()" call. This tells Grails/GORM/Hibernate explicitly to attempt an INSERT operation rather than an UPDATE one.
All of the stars and planets must be in alignment for this to work right. If your domain class "static mapping {}" block does not set the Hibernate generator to "assigned", and also set "version false", then Grails/GORM/Hibernate will still get confused and try to issue an UPDATE rather than an INSERT.
If you are using auto-generated Grails Scaffolding controllers, then it is safe to use "insert: true" in the Controller's "save()" function, because that function in only called when saving a new object for the first time. When a user edits an existing object, the Controller's "update()" function is used instead. However, if you are doing your own thing in your own custom code somewhere... it will be important to check on whether a domain object is already in the the database before you make a ".save()" call, and only pass the "insert: true" parameter if it really is a first-time insert.
Issue #4: Using natural keys with Grails/GORM/Hibernate
One final note, not having to do with Oracle GUID values, but related to these Grails issues in general. Let's say that in a legacy database (such as the one I've been dealing with), some of your tables use a natural key as their primary key. Say you have an OWNER_TYPE table, containing all the possible "types" of OWNER, and the NAME column is both the human-readable identifier as well as the primary key.
You'll have to do a couple of other things to make this work with Grails Scaffolding. For one thing, the auto-generated Views do not show the ID field on the screen when users are creating new objects. You will have to insert some HTML to the relevant View to add a field for the ID. If you give the field a name of "id", then the auto-generated Controller's "save()" function will receive this value as "params.id".
Secondly, you have to make sure that the auto-generated Controller's "save()" function properly inserts the ID value. When first generated, a "save()" starts off by instantiating a domain object from the CGI parameters passed by the View:
def ownerTypeInstance = new OwnerType.get( params )
However, this does not handle the ID field you added to your View. You will still need to set that manually. If on the View you gave the HTML field a name of "id", then it will be available in "save()" as "params.id":
...
ownerTypeInstance = new OwnerType()
ownerTypeInstance.id = params.id
// Proceed to the ".save()" step, making sure to pass "insert: true"
...
Piece of cake, huh? Perhaps "Issue #5" is figuring out why you put yourself through all this pain, rather than just writing your CRUD interface by hand with Spring Web MVC (or even vanilla JSP's) in the first place! :)
Support for using SYS_GUID() is dependent upon the Oracle dialect that you are using. Looking at the hibernate source on GitHub it appears that the dialect was only setup to use the Oracle-generated guid in Oracle9Dialect.java and Oracle8iDialect.java. Therefore, it won't work with the 9i or 10g dialects.
You should submit a patch to hibernate which will add the required function(s) to enable the same functionality as the other dialects.

Resources