Grails - Spring Security not working with Mysql 8 - java

I have a application where I used these technologies:
Grails 3.3.0
JDK 1.8
Spring 4+
Mysql 8
GORM 6.1.6.RELEASE
org.grails.plugins:spring-security-core:3.2.0
Hibernate 5+
Problem is when I am trying to connect the application with Mysql 8(with 5.6+ it is working fine), I am not able to get the information related to user from Grails-Spring-Security plugin.
The application is running even connect to DB but wont be able to authenticate or fetch the information of the User like findByUsername where username is property in my user domain class.
I have User domain class defined in application.properties file.
grails.plugin.springsecurity.userLookup.userDomainClassName = 'com.aaa.User'
At some point I found this error but not sure whether it is related to this or not.
java.lang.IllegalStateException:
Either class [com.aaa.User] is not a domain class or GORM has not been initialized correctly or has already been shutdown.
Ensure GORM is loaded and configured correctly before calling any methods on a GORM entity.
Want to understand why it wont be able to fetch the information from DB. I have tried lot of things like change the GORM version to 6.1.7 and grails spring-secuirty-core plugin version but not able to get anything.
Any help would be appreciated.
Thanks,
Atul

We are able to solve the issue. It happens when grails-hibernate plugin look for the property(in my case its username as I am calling API findByUsername) which is present in the static api or not. If it is not there it throws the exception.
The thing worked for me is, I have to put the property in static mapping of User domain class:
static mapping = {
table 'userTable'
id column: 'id'
password column: 'userpassword'
username column: 'username'
}
I am not sure why it is happening, when I run the application with Mysql5.6+ its working.(The driver is according to it) but when go with Mysql8, it look for the property in static mapping.
One more point I would like to mention to fix the issue is, make sure you have tablename, columnname same as defined in DB. Case sensitivity is what expected.
As I mentioned the case sensitivity, if you are using linux with Mysql8, the lower_case_table_names=0, this check with the following as per Mysql official documentation:
Table and database names are stored on disk using the lettercase
specified in the CREATE TABLE or CREATE DATABASE statement. Name
comparisons are case sensitive. You should not set this variable to 0
if you are running MySQL on a system that has case-insensitive file
names (such as Windows or macOS). If you force this variable to 0 with
--lower-case-table-names=0 on a case-insensitive file system and access MyISAM tablenames using different lettercases, index corruption
may result.
So if the table name is static is in camel or upper case and in db it is lower case it wont match. and the error occurred.
Hope this helps to someone.

Related

How to see all tables in my h2 database at localhost:8082?

I use JDBC and created h2 database called usaDB from sql script. Then I filled all tables with jdbc.
The problem is that after I connect to usaDB at localhost:8082 I cannot see on the left tree
my tables. There is only INFORMATION_SCHEMA database and rootUser which I specified creating usaDB.
How to view the content of tables in my h2 database?
I tried query SELECT * FROM INFORMATION_SCHEMA.TABLES.
But it returned many table names except those I created. My snapshot:
I had the same issue and the answer seems to be really stupid: when you type your database name you shouldn't add ".h2.db" suffix, for example, if you have db file "D:\somebase.h2.db" your connection string should be like "jdbc:h2:file:/D:/somebase". In other way jdbc creates new empty database file named "somebase.h2.db.h2.db" and you see what you see: only system tables.
You can use the SHOW command:
Using this command, you can lists the schemas, tables, or the columns of a table. e.g.:
SHOW TABLES
This problem drove me around the twist and besides this page I read many (many!) others until I solved it.
My Use Case was to see how a SpringBatch project created in STS using :: Spring Boot :: (v1.3.1.RELEASE) was going to behave with the H2 database; to do the latter, I needed to be able to get the H2 console running as well to query the DB results of the batch run.
This is what I did and found out:
Created an Web project in STS using Spring Boot:
Added the following to the pom.xml of the latter:
Added a Spring configuration file as follows to the project:
This solves the Web project deficiencies in STS. If you run the project now, you can access the H2 console as follows: http://localhost:8080/console
Now create a SpringBatch project in STS as follows (the alternative method creates a different template missing most of the classes for persisting data. This method creates 2 projects: one Complete, and the other an initial. Use the Complete in the following.):
The SpringBatch project created with STS uses an in memory H2 database that it CLOSES once the application run ends; once you run it, you can see this in the logging output.
So what we need is to create a new DataSource that overrides the default that ships with the project (if you are interested, just have a look at the log messages and you will see that it uses a default datasource...this is created from:
o.s.j.d.e.EmbeddedDatabaseFactory with the following parameters:
Starting embedded database: url='jdbc:hsqldb:mem:testdb', username='sa')
So, it starts an in memory, and then closes it. You have no chance of seeing the data with the H2 console; it has come and gone.
So, create a DataSource as follows:
You can of course use a properties file to map the parameters, and profiles for different DataSource instances...but I digress.
Now, make sure you set the bit that the red arrow in the picture is pointing to, to a location on your computer where a file can be persisted.
Running the SpringBatch (Complete project) you should now have a db file in that location after it runs (persisting Person data)
Run the Web project you configured previously in these steps, and you WILL :=) see your data, and all the Batch job and step run data (et voila!):
Painful but rewarding. Hope it helps you to really BOOTSTRAP :=)
I have met exactly this problem.
From what you describe, I suppose that you connect your jdbc with the "real" h2 server, but you are connecting on web application to database by the wrong mode (embedded-in-memory mode, aka h2mem). It means that h2 will create a new database in-memory, instead of using your true database stored elsewhere.
Please make sure that when you connect to this database, you use the mode Generic H2 (Server), NOTGeneric H2 (Embedded). You can refer to the picture below.
Version of jar file and installed h2 database should be same.
If in case you have created and populated H2 database table using maven dependency in spring boot, then please do change the JDBC URL as jdbc:h2:mem:testdb while connecting to H2 using web console.
It is an old question, but I came across the same problem. Eventually I found out that the default JDBC URL is pointing a test server rather than my application. After correcting it, I could access the right DB.
I tried with both Generic H2 (Embedded) and the Generic H2 (Server) options, both worked as long as the JDBC URL: is provided correctly.
In grails 4.0.1 the jdbc URL for development is jdbc:h2:mem:devDb. Check your application.yml file for the exact URL.
For the people who are using H2 in embedded(persistent mode) and want to "connect" to it from IntelliJ(other IDEs probably apply too).
Using for example jdbc url as follows: jdbc:h2:./database.h2
Note, that H2 does not allow implicit relative paths, and requires adding explicit ./
Relative paths are relative to current workdir
When you run your application, your workdir is most likely set to your project's root dir
On the other hand, IDE's workdir is most likely not your project's root
Hence, in IDE when "connecting" to your database you need to use absolute path like: jdbc:h2:/Users/me/projects/MyAwesomeProject/database.h2
For some reason IntelliJ by default also adds ;MV_STORE=false. It disables MVStore engine which in fact is currently used by default in H2.
So make sure that both your application and your IDE use the same store engine, as MVStore and PageStore have different file layouts.
Note that you cannot "connect" to your database if your application is using it because of locking. The other way around applies too.
In my case the issue was caused by the fact that I didn't set the h2 username, password in java. Unfortunatelly, Spring didn't display any errors to me, so it was not easy to figure out. Adding this lines to dataSource method helped me fix the issue:
dataSource.setUsername("sa");
dataSource.setPassword("");
Also, I should have specified the schema when creating tables in schema.sql
Selecting Generic H2 (Server) solved for me. We tempted to use default Generic H2 (Embedded) which is wrong.

PlayFramework - Error when deploying to Heroku (pgsql 'user' table)

I have recently been writing an application using Play (great framework, can't really fault it). However, I'm getting a weird error when pushing the app to Heroku.
2013-08-12T15:52:17.641129+00:00 app[web.1]: [←[31merror←[0m] play - ERROR: synt
ax error at or near "user"
2013-08-12T15:52:17.744588+00:00 app[web.1]: Position: 14 [ERROR:0, SQLSTATE:4
2601]
That's where it seems to be going wrong.
The weird aspect of the error is the fact I don't have any tables or references to 'user' in my SQL-related code (evolutions, models and even my database). Would it be an issue with something being cached?
Thanks in advance,
Adil
EDIT
I seem to have fixed the error:
I deleted the evolution scripts, for some reason they were filled
with data I didn't need (e.g sql scripts to create a 'user table')
I updated all my references to the user table (even class names) to
'AppUser' (this is changeable).
I ran sql queries on the pgsql database directly, creating the tables manually.
I then disabled the
evolutions plugin and removed the jdbc username and password when
committing to heroku.
Postgresql has a default "user" table. I would recommend naming your table something else like member. It will conflict with it otherwise. Caps might work, or tildes `user`, but even then I'd recommend using a different name for the table. Wipe your table just in case there is an evolution backup.

What happens if I change name of a field in a grails domain?

I had a grails domain with a field named created Though now I've changed it to dateCreated. However, my database table still has the column named created so anytime I try to save a record grails complains saying Field 'created' doesn't have a default value even though I no longer have this field in my domain.
How does one get around this issue? Do I have to open my db and delete this column? In rails this is handled through migrations, what is the equivalent in grails?
If you just rename the domain field, you can specify column name in the mapping block, and not change it when you rename the related field. So, no DB changes will be needed at all.
class MyDomain {
Date dateCreated
static mapping = {
dateCreated column: 'created'
}
}
You must specified dbCreate = "update" in your DataSource.groovy.
If you are in development stage, you can change it to dbCreate = "create" to enable automatic schema refresh. Otherwise, in a production environment, you have to keep that configuration and alter the table manually.
You may refer to Grails DataSource doc, which also proposed some migration tools:
You can also remove the dbCreate setting completely, which is
recommended once your schema is relatively stable and definitely when
your application and database are deployed in production. Database
changes are then managed through proper migrations, either with SQL
scripts or a migration tool like Liquibase (the Database Migration
plugin uses Liquibase and is tightly integrated with Grails and GORM).

How to set default schema in a Spring/mybatis application with Oracle DB?

Coming from a mysql background, I am able to set the default schema name that I want to use for all my sql queries in the connection url. I now have an Oracle DB that I need to access. I am aware that I cannot specify the schema I want to use in the URL since the user is the schema name being used.
I realize that I can use a line of SQL code:
ALTER SESSION SET CURRENT_SCHEMA=default_schema
The project is using mybatis 2.3.5 as my SQL framework, but I am completely new to mybatis. Is there a simple way to configure mybatis to accomplish this? My application is a Spring 3 application, so I am using the Spring DataSourceTransactionManager to manage my transactions. I would presume that the manager must be made aware of this requirement to ensure that the command is sent whenever creating a new connection.
I've tried searching online, but most of the examples I find all have the schema names included within the sql queries in the SqlMaps, which I find to be bad practice.
In an ideal world, the schema name would be part of the URL such that I can make changes to the schema name for different environments (ex: dev, test, prod, etc) without touching the code (ie: only configured at the JNDI/application server level). I would be happy if I could use a Spring configuration value to set this as well as I could still use a JNDI lookup or a system environment property to retrieve the value.
Can anyone point me in the right direction?
Thanks,
Eric
As far as I know, there is no option in Oracle to change your URL in order to connect to a specific user schema.
1) mybatis: You may set your current schema to a deserved one before you start your operations. You can write your specification in a property file and set your method's arguments from that file. You do not need to change your code to change your schema in that case.
<update id="mySetSchemaMethod" parameterClass="String">
ALTER SESSION SET CURRENT_SCHEMA = ${schemaName}
</update>
2) trigger: If you are using this connection only for this particular java application, you can set a client event trigger so set your CURRENT_SCHEMA. This time, you need to change the trigger in order to manage test/prod changes.
CREATE OR REPLACE TRIGGER Set_Schema_On_Logon
AFTER LOGON
ON MY_SCHEMA
BEGIN
ALTER SESSION SET CURRENT_SCHEMA = MY_TEST_SCHEMA;
END;

DB2 JDBC broke spring named parameter mapping

We've got an application using spring for making calls to DB2 stored procedures.
The application was working fine with jdbc version 1.XX.XX (and DB2 V8). An recent upgrade to DB2 V9 moves us to using jdbc versiong 3.58.90 instead.
However, this seems to have broken the named parameters mapping in spring (version 2.5.5). Some previously working code had call string
call storedproc123(:id,:date)
now throws exceptions with
[jcc][t4][10427][12544][3.58.90] Error parsing FLOAT literal value starting at index 19. Error Detail:Unexpected character ':' found in FLOAT literal.
...
ERRORCODE=-4463, SQLSTATE=42601
...
Has anyone encountered something similar?
Thanks in advance!
---edited to add more info---
I've tried swapping the old jdbc back after the upgrade. The application works just fine with the old driver, however we'd like to upgrade to the newer version since another app on the same server needs this newer jdbc, and it's difficult to have different versions of the same jdbc deployed on our server (we uses JBoss).
http://redneckprogrammer.blogspot.com/2009/10/running-multiple-versions-of-oracle.html discussed how to deploy multiple versions of the same JDBC driver, however this seems to be too much of a hack and I'd like to avoid it if at all possible.
Found the cause, see IBM patch PK87567 .
...
All Connectivity: Driver code has been enhanced to support
a new API on com.ibm.db2.jcc.DB2ParameterMetaData:
getParameterMarkerNames, which returns a list of parameter
marker names used in the SQL Statement as a String .
This method returns null if property
enableNamedParameterMarkers is set to
DB2BaseDataSource.NOT_SET or DB2BaseDataSource.NO, or if
there are no named parameter markers in the SQL Statement.
The list returned contains unique parameter marker names.
If a named parameter marker appears more than once in the
SQL Statement, it will only appear once in the list
returned. (120191)
...
Fixed the problem by enabling the marker.

Categories