I'm using the grails database migration plugin: runtime ':database-migration:1.4.1'. For the initial changelog everything seems to work, even going from an H2 development database to mysql.
However, I wanted to test an actual model change, and I'm getting an error I can't figure out.
We have the following User model:
class User {
// spring security params:
transient springSecurityService
String username
String password
// Added this to test model changes:
String removeme
...
static mapping = {
password column: '`password`'
}
}
When I go to generate the diff, i.e.
grails dbm-gorm-diff --add change_test.groovy
I get the following exception:
liquibase.exception.DatabaseException: org.h2.jdbc.JdbcSQLException: Column "PASSWORD" not found; SQL statement:
SELECT password FROM user WHERE 1 = 0 [42122-176]
at liquibase.snapshot.jvm.JdbcDatabaseSnapshotGenerator.createSnapshot(JdbcDatabaseSnapshotGenerator.java:251)
at liquibase.snapshot.DatabaseSnapshotGeneratorFactory.createSnapshot(DatabaseSnapshotGeneratorFactory.java:69)
at liquibase.diff.Diff.compare(Diff.java:71)
at grails.plugin.databasemigration.GormDiff.compare(GormDiff.groovy:45)
at grails.plugin.databasemigration.ScriptUtils.createAndPrintFixedDiff(ScriptUtils.groovy:244)
at DbmGormDiff$_run_closure1$_closure2$_closure3.doCall(DbmGormDiff:53)
at grails.plugin.databasemigration.MigrationUtils.executeInSession(MigrationUtils.groovy:137)
at DbmGormDiff$_run_closure1$_closure2.doCall(DbmGormDiff:50)
at grails.plugin.databasemigration.ScriptUtils.executeAndWrite(ScriptUtils.groovy:104)
at DbmGormDiff$_run_closure1.doCall(DbmGormDiff:49)
Caused by: org.h2.jdbc.JdbcSQLException: Column "PASSWORD" not found; SQL statement:
SELECT password FROM user WHERE 1 = 0 [42122-176]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:344)
at org.h2.message.DbException.get(DbException.java:178)
at org.h2.message.DbException.get(DbException.java:154)
at org.h2.expression.ExpressionColumn.optimize(ExpressionColumn.java:148)
at org.h2.command.dml.Select.prepare(Select.java:831)
at org.h2.command.Parser.prepareCommand(Parser.java:248)
at org.h2.engine.Session.prepareLocal(Session.java:442)
at org.h2.engine.Session.prepareCommand(Session.java:384)
at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1188)
at org.h2.jdbc.JdbcStatement.executeQuery(JdbcStatement.java:75)
at liquibase.snapshot.jvm.JdbcDatabaseSnapshotGenerator.isColumnAutoIncrement(JdbcDatabaseSnapshotGenerator.java:842)
at liquibase.snapshot.jvm.JdbcDatabaseSnapshotGenerator.readColumns(JdbcDatabaseSnapshotGenerator.java:369)
at liquibase.snapshot.jvm.JdbcDatabaseSnapshotGenerator.createSnapshot(JdbcDatabaseSnapshotGenerator.java:244)
I can simply remove the removeme column and everything works as expected. This is only in our dev environment too, so only regarding the H2 database.
I solved this pretty much based on this answer:
How can I use Grails DB Migration with Spring Security and the default DB, H2?
Changed this
static mapping = {
password column: '`password`'
}
to
static mapping = {
password column: 'passwd'
}
Basically the above is preferred (IMO) because it avoids confusion in the database engine, and having to deal with weird escaping -- by just using something that isn't generally a reserved word.
Related
In a Grails/GORM app, can I rename the implicit domain id column to entity_id and auto-increment using an existing sequence?
class Practitioner {
Long entityId
String providerName
static mapping = {
id name: 'entityId', column: 'entity_id', generator:'sequence', params:[sequence:'hibernate_sequence']
}
}
Attempting to save in console fails, (and yes, sequence exists in my local Postgres database)
Practitioner p = new Practitioner(providerName: 'p')
p.save(flush:true, failOnError: true)
Error
grails.validation.ValidationException: Validation Error(s) occurred during save():
- Field error in object
'com.transcendinsights.dp.measureresult.snapshot.Practitioner' on field 'entityId': rejected value [null]; codes
Super thanks for helping!
My Grails application and bootstrap work fine when dbCreate="create", but when I change it to dbCreate="update", I get object create validation errors in bootstrap. I'd just like my data to persist when I restart the application. From the error message, it appears I'm violating a unique constraints. Maybe the database isn't getting purged on restart? I've tried "create-drop"
Here is the code and error message below. Any insight is appreciated.
development {
dataSource {
dbCreate = "create-drop" // one of 'create', 'create-drop', 'update', 'validate', ''
url = "jdbc:h2:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;"
}
}
class BootStrap {
def init = { servletContext ->
def adminRole = new com.testapp.Role(authority: 'ROLE_ADMIN').save(failOnError: true)
def userRole = new com.testapp.Role(authority: 'ROLE_USER').save(failOnError: true)
}
Message:
Validation Error(s) occurred during save():
- Field error in object 'com.testapp.Role' on field 'authority': rejected value [ROLE_ADMIN]; codes [com.testapp.Role.authority.unique.error.
default message [Property [{0}] of class [{1}] with value [{2}] must be unique
I think you must have already created the Role with Authority "ROLE_ADMIN" or "ROLE_USER". The second time you are running with update gives an error because of unique constraint. An attempt is being made to create role with same Authority names and it throws error.
You should apply a condition such that if a role already exist, you should not try to create the same again.
I am using ASP.NET MVC 4 (.NET framework 4.5) with LINQ-to-SQL and SQL Server 2008 R2
This function returns always true if I run it through debug mode, but when I run it without debug, it returns false. I once got this error: http://i.imgur.com/HydhT.png
I tried googling this, some similiar problems came up but I checked them all:
UserProfiles table has a primary key
The datacontext is in sync with the database
I've tried putting ConflictMode.ContinueOnConflict as an argument in SubmitChanges()
I've tried to put above the facebookID in LINQ designer: UpdateCheck=UpdateCheck.Never
Nothing works. I have never experienced anything like this before. Does anyone have any idea?
Code:
facebookID field in SQL Server is varchar(50) NULL with default value NULL
public static bool changeFacebookIDByEmail(string email, string facebookID)
{
UserProfile profile = (from s in _dc.Users
join u in _dc.Memberships on s.UserId equals u.UserId
join i in _dc.UserProfiles on u.UserId equals i.userID
where u.Email == email
select i).SingleOrDefault();
profile.facebookID = facebookID;
ChangeSet cs = _dc.GetChangeSet();
_dc.SubmitChanges();
if (cs.Updates.Count <= 0)
return false;
else
return true;
}
It seems like you are executing a manual SQL statement:
UPDATE UserProfiles SET facebookID = NULL WHERE userID = '85A6D951-15C8-4892-B17D-BD93F3D0ACBB'
This will set the facebookID to null. Entity framework does not know this, though. It cannot interpret raw SQL. So it still thinks the facebookID is set to some value. When you later set it to that value in changeFacebookIDByEmail EF thinks nothing changed.
Sou you probably should not execute raw SQL strings. Use EF to change the value to null.
Change .singleordefault to .single I think your problem will be revealed pretty soon after that.
Basically anything found by your query with be in the datacontext. Anything new eg default will not.
You need to rewrite your routine to insert the new user in the case where it's not found.
EDIT
This is some code from a project I have been working on. I've cut out a bunch of stuff to demonstrate how it should work.
// add the identity as necessary
var found = dB.Identities.SingleOrDefault(q => q.UserName == userName);
if (found == null)
{
found = new Identity
{
Domain = domain,
Password = User.Identity.AuthenticationType,
Salt = "",
UserName = userName,
LastUpdatedDateTime = DateTime.Now
};
dB.Identities.InsertOnSubmit(found);
}
dB.SubmitChanges(null);
We are using grails with groovy and recently changed database from MySQL to Oracle 11g. We took care of table names like USER, RESOURCE to make it something else, remapped the new names in the domain classes.
I also added some default data in roles from mysql table(for spring security to work) and inserted one user 'admin' manually in GRAUSER table (renamed from USER).
The server does start up in Netbeans
But when I try to login I get the following error
ERROR util.JDBCExceptionReporter ORA-00904: "THIS_"."password": invalid identifier
Not able to debug the cause of this. Let me know if any more details/code is needed to review, but I need to be able to login to the application.
Could you post your DataSource.groovy file? Below is roughly what mine looks like for connecting to Oracle.
dataSource {
logsql = true
pooled = true
driverClassName = "oracle.jdbc.OracleDriver"
username = "user"
password = "secret"
dialect='org.hibernate.dialect.Oracle10gDialect'
}
environments {
development {
dataSource {
//dbCreate = "create-drop" // one of 'create', 'create-drop','update'
url = "jdbc:oracle:thin:#server:1521:sid"
}
}
}
I'm following the racetrack example from Jason Rudolph's book at InfoQ, using grails-1.2.1. I got up to the part where I was to switch from hsqldb to mysql. I think I've deleted every reference to hsqldb in the DataSource.groovy file, but I get an exception and the stack trace shows it's still using hsqldb.
DataSource.groovy
dataSource {
boolean pooled = true
String driverClassName = "com.mysql.jdbc.Driver"
String url = "jdbc:mysql://localhost/dfpc2"
String dbCreate = "create"
String username = "dfpc2"
String password = "dfpc2"
dialect = org.hibernate.dialect.MySQL5InnoDBDialect
}
hibernate {
cache.use_second_level_cache=true
cache.use_query_cache=true
cache.provider_class='net.sf.ehcache.hibernate.EhCacheProvider'
}
// environment specific settings
environments {
development {
}
test {
}
production {
}
}
When I grails run-app it all starts up with no errors. I can navigate to the home page. But when I click on one of the links, I get a stack trace:
java.sql.SQLException: Table not found in statement [select this_.id as id0_0_, this_.version as version0_0_, this_.name as name0_0_, this_.variant as variant0_0_ from domainObject this_ limit ?]
at org.hsqldb.jdbc.Util.throwError(Unknown Source)
at org.hsqldb.jdbc.jdbcPreparedStatement.<init>(Unknown Source)
at org.hsqldb.jdbc.jdbcConnection.prepareStatement(Unknown Source)
at dfpc2.domainObjectController$_closure2.doCall(script1269434425504953491149.groovy:13)
at dfpc2.domainObjectController$_closure2.doCall(script1269434425504953491149.groovy)
at java.lang.Thread.run(Thread.java:619)
My mysql database shows no tables created. (I don't think groovy's connected to mysql yet.)
Things I've checked:
mysql-connector-java-5.1.6.jar is in lib directory.
I've tried grails clean
I tried putting the dataSource info in the development environment (I haven't graduated to test or prod yet), but it seemed to make no difference. The stdout shows I'm using development env.
I've googled for solutions, but the only solution I've found is when people don't change the test or production environments.
Problem was the type declarations. Instead of
dataSource {
boolean pooled = true
String driverClassName = "com.mysql.jdbc.Driver"
String url = "jdbc:mysql://localhost/dfpc2"
String dbCreate = "create"
String username = "dfpc2"
String password = "dfpc2"
dialect = org.hibernate.dialect.MySQL5InnoDBDialect
}
should have had:
dataSource {
pooled = true
driverClassName = "com.mysql.jdbc.Driver"
url = "jdbc:mysql://localhost/dfpc2"
dbCreate = "create"
username = "dfpc2"
password = "dfpc2"
dialect = org.hibernate.dialect.MySQL5InnoDBDialect
}
Found the answer in the grails doco:
When configuring the DataSource do not include the type or the def keyword before any of the configuration settings as Groovy will treat these as local variable definitions and they will not be processed. For example the following is invalid:
boolean pooled = true
That book is way out of date and InfoQ should pull it or add a link to the 2nd edition which came out recently and is based on Grails 1.2: http://www.infoq.com/minibooks/grails-getting-started