FindBy columnName when column name contains "Id" - mysql

In Grails, Gorm, I have this entity:
class MyEntity implements Serializable {
Long bankTransactionId
int version
BigDecimal someValue
static constraints = {
bankTransactionId(nullable: false)
version(nullable: true)
someValue(nullable: true)
}
}
Doing MyEntity.findByBankTransactionId(Long.valueOf("3")) throws this exception:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown
column 'this_.id' in 'field list'
I am suspecting the fact that my column has the name id in it. Could it be this?
How to fix it then ?
Thanks.

Everything you have provided here looks fine. In particular, there are no restrictions about having the letters "id" in a column name.
Take a look at your generated MySQL table. I'm guessing that the id column isn't there for some reason. Maybe something prevented generating it due to some earlier error that you have now corrected, or you have your datasource set to "none" instead of "update" (or similar) and the whole table is missing!
If this is just a development environment with no real data (and no foreign key constraints), drop the whole MyEntity table and let it be automatically recreated. If not, move to a different temporary datasource, let a new table be created, and compare the two. If the new one still doesn't have an id column, you have something going wrong during your startup that is preventing your tables from being created correctly. You could just add the column in manually, but if you don't figure out what happened to it in the first place, it will probably just happen again.
For reference, in my test environment, my MySQL table for "MyEntity" copied from your example looks like:
desc my_entity;
'id','bigint(20)','NO','PRI',NULL,'auto_increment'
'version','int(11)','YES','',NULL,''
'bank_transaction_id','bigint(20)','NO','',NULL,''
'some_value','decimal(19,2)','YES','',NULL,''

Related

Delete many2many column in table and the table itself - odoo 13

While running a pre-migration script to delete a (wizard) transient model, ended up with below mentioned issue.
from openupgradelib import openupgrade
#openupgrade.migrate()
def migrate(env, version):
openupgrade.delete_records_safely_by_xml_id(
env,
["moduel_name.view_id)"],
delete_childs=True,
)
try:
env.cr.execute("DROP TABLE IF EXISTS table_name CASCADE")
env.cr.execute("DROP TABLE IF EXISTS dependent_table_names CASCADE")
except Exception as e:
raise ("Exception--------------", e)
Error:
psycopg2.errors.ForeignKeyViolation: update or delete on table "ir_model" violates foreign key constraint "ir_model_relation_model_fkey" on table "ir_model_relation"
Similar issue: https://github.com/odoo/odoo/issues/54178
According to the above issue, having Many2many in transient model might cause this issue. It is true in my case as well. I have many2many fields. No solution there.
I kind of tried deleting the problematic fields(Many2many) before deleting columns. But it is known that many2many fields can't be located in db. kind of stuck.
openupgrade.drop_columns(
env.cr,
[
("table_name", "any_other_column_name"), # ---> This works
("table_name", "many2many_column_name"), # ---> This doesn't
],
)
is there anyway to get rid of many2many fields from the model ? Any help is appreciated.
Could you try this :
Let's say your Transient is my_transient_model and the Many2many field is e.g. sale_line_ids = fields.Many2many('sale.order_line')
First thing to know : Did you specify the relation table ? like
sale_line_ids = fields.Many2many('sale.order_line', 'my_relation_table_name') ?
If so, 'my_relation_table_name' is the name you want to delete from ir_model_relation.
If not, the relation table name is my_transient_model_sale_order_line_rel (so model then _ then the model we point to with _ instead of . then _rel.
Second set: delete the data from ir_model_relation:
DELETE FROM ir_model_relation WHERE name='my_transient_model_sale_order_line_rel';
Then you should be able to delete the Many2many table :
DROP TABLE my_transient_model_sale_order_line_rel;
(for sure, change my_transient_model_sale_order_line_rel if you specified the relation table like my_relation_table_name in the example)
Hope it helped, keep me updated :)

Grails: Db row update fails silently when domain class contains 'version false'

I'm using grails v3.2.9
I have a domain class Offer containing
static mapping = {
version false
}
I insert a row to a offer table, then in another transaction I try to update a value of one column inside that row, but offer update silently fails while other entities in the same transaction are updated properly.
I save the offer as follows:
offer.save(failOnError: true)
so it is not the case of offer.save() when the validation fails and saving fails silently.
However if I add version column to offer table(dbCreate is set to none) and change the Offer domain class to contain
static mapping = {
version true
}
the row starts to be updated successfully.
When I inspect the audit_log for offer table there is only the insertion events, no any update event is there.
It is very weird as I have other domain classes containing version = false and updating there works fine.
Any help would be appreciated.
Since version = false, the property Offer.version is equal to null and the column does not exist in database. Normally when you perform updates Hibernate will automatically check the version property against the version column in the database. So, I am just guessing it may be a bug with the hibernate session trying check a value that is null. I tried to replicate your scenario but I did not succeed.
Have you tried flushing the session when you save?:
offer.save(flush: true, failOnError: true)
It is also possible that when you changed the domain that required version to a domain that doesn't require version, the underlying database table didn't drop that column.
By default the version column is created as NOT NULL in the physical database. Even though hibernate doesn't care about the version property in the domain, the physical database won't let that record inserted and hence it fails.
While this explains why a record is not inserted, it doesn't explain why it doesn't throw an error. It shouldn't fail silently and instead throw a SQL exception.

EF and Code First Migrations with MySQL - dbo.tablename does not exist

I have set up entity framework to use MySQL and created a migration.
When I run update-database I get error "table dbname.dbo.tablename' does not exist. Running in -Verbose mode I see the statement that causes the error :
alter table `dbo.Comments` drop foreign key `FK_dbo.Comments_dbo.Comments_Comment_ID`
When I run the query direct in MySQL workbench is throws the same error.
The problem seems to be the dbo. prefix in the migration set. Anything in the form dbo.tablename won't run saying that table does not exist. E.g. select * from dbo.tablename fails but select * from tablename works. The database was generated by Entity Framework and the code first migrations were generated by EF too.
However the migrations generate everything with the dbo. prefix, which does not work.
Does anyone have a solution to this?
I was having this problem just today as well; found my answer here:
MySqlMigrationCodeGenerator
You have to set:
CodeGenerator = new MySqlMigrationCodeGenerator();
In your context's configuration class. This will get rid of the schema gibberish for MySQL. My Configuration class looks like this:
internal sealed class Configuration : DbMigrationsConfiguration<YourContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
SetSqlGenerator("MySql.Data.MySqlClient", new MySqlMigrationSqlGenerator());
SetHistoryContextFactory("MySql.Data.MySqlClient", (conn, schema) => new MySqlHistoryContext(conn, schema));
CodeGenerator = new MySqlMigrationCodeGenerator();
}
}
I have this same issue and I applied the solution posted by Sorio and It generated a lot of problems.
CodeGenerator = new MySqlMigrationCodeGenerator();
This code line can change all the sql that you generate, for example in my case in the sql code to apply to the database all the foreign key constraints disappear.
I am still without a solution because for me this is not acceptable and I recommend you to check the sql generate with the command before use this solution:
update-database -script

Tell Hibernate's hbm2ddl to add MySQL enum columns for #Enumerated annotated fields

I'm creating a DB table using hbm2ddl with Java code similar to the following:
#Entity
public class Filter {
public enum Type {
TypeA, TypeB;
}
#Enumerated(EnumType.STRING)
private Type type;
}
It works fine, but for "type" a VARCHAR column is created, i.e. the DDL code looks like this:
CREATE TABLE IF NOT EXISTS `filter` (`type` varchar(255) DEFAULT NULL)
But what I want to have is this:
CREATE TABLE IF NOT EXISTS `filter` (`type` enum('TypeA','TypeB') NOT NULL)
Is this possible to declare in Hibernate, preferred with annotations?
Or is there a way to extend SchemaUpdate and overwrite the method that renders the alter script part for enumerated field the way I like it?
Background: The same database is used in a PHP part of the project and I want to prevent that invalid values are inserted.
Although it seems there is no way to handle MySQL enums 100% automatically, as pointed out by Lucas on his answer, there is actually a simple way to contour it. You may use columnDefinition attribute on #Column annotation, which seems to be specifically designed to generate custom DDL code.
See the documentation excerpt describing the attribute:
(Optional) The SQL fragment that is used when generating the DDL for the column.
Defaults to the generated SQL to create a column of the inferred type.
The NOT NULL restriction is quite standard, and is supported by another attribute nullable.
Thus, your property definition would look like this:
#Enumerated(EnumType.STRING)
#Column(columnDefinition = "enum ('TypeA', 'TypeB')", nullable = false)
private Type type;
I believe that's going to be complicated, since the java.sql.Types, which define the sql types treated by java, does not have enum type (since it's not a standardized type according to SQL-92).
If that was the case you could create a hibernate custom UserType extending the EnumType and setting the sqlType accordingly, but since java.sql.Types doesn't handle it I don't see how to use native sql enum.
best regards!

Select one column from a row in hibernate

I am trying to do a simple query to get a unique result back in hibernate here is my code.
public String getName(Integer id) {
Session session = getSessionFactory().openSession();
String name = (String)session.createSQLQuery("SELECT name FROM users WHERE user_id = :userId").setParameter("userId", id).uniqueResult();
return name;
}
The name that is being returned is stored as HTML text that includes html syntacx language. I think this is what is causing the problem but it doesnt make sense I just want to return it as a string.
It is only happening on this one field name, I can get every other field in the row but this one it gives me the error.
I am getting an exception. The exception I am getting is
No Dialect mapping for JDBC type: -1; nested exception is org.hibernate.HibernateException
How do you query for a specific column on a row in hibernate?
I figured out the solution, apparently Java has not type that can be mapped to Text fields so you have to add a scalar solution below: Thanks for the help
session.createSQLQuery("SELECT name FROM users WHERE user_id = :userId").addScalar("name", Hibernate.TEXT).setParameter("userId", id).uniqueResult();
Then that should work. Use the Type hibernate annotation.
Add
#Type(type="text")
To your mapping.