Grails: Joda LocalDate as unique key in a MySQL database - mysql

I have a domain class with a Joda LocalDate property. This property must be unique.
It works using an H2, but using a MySQL db I have this error on app boot:
[SchemaExport.create(l.386)]Unsuccessful: create table [...]
[SchemaExport.create(l.387)]BLOB/TEXT column 'mydate' used in key specification without a key length
If a remove unique constraint, it works also with MySQL.
Is it a bug or my misunderstanding?
I'm using Grails 2.2.5.
Here domain fragment:
class MyClass {
LocalDate mydate
static constraints = {
mydate(nullable:false, unique:true)
}
}
DataSource config fragment:
dataSource {
dbCreate = "create-drop"
driverClassName = "com.mysql.jdbc.Driver"
dialect = org.hibernate.dialect.MySQL5InnoDBDialect
username = "xxx"
password = "xxx"
dbNamer = "myapp"
url = "jdbc:mysql://localhost:3306/${dbNamer}?autoreconnect=true"
logSql = true
}

wild guess, I think that date is reserved word in mySQL. rename the field and try again
UPDATE:
ok, I see.
the problem is, that GORM/Hibernate is not aware of joda LocalDate class, so it's trying to create a BLOB column for it:
[SchemaExport.create(l.387)]BLOB/TEXT column 'mydate'`.
To fix it, you can either use a custom hibernate type (have no idea how), or convert the property into a plane java's Date class by saving, and back to LocalDate after loading

Related

Why the second database not created when multiple datasources in Springboot application?

I want to use two (Mysql) databases in my Springboot application. Following the instructions I use the following configuration
app.properties
spring.datasource.url = jdbc:mysql://localhost:3306/db1?createDatabaseIfNotExist=true&autoReconnect=true
spring.datasource.username = root
spring.datasource.password = password
spring.seconddatasource.url = jdbc:mysql://localhost:3306/db2?createDatabaseIfNotExist=true&autoReconnect=true
spring.seconddatasource.username = root
spring.seconddatasource.password = password
DataSourceConfig.java
#Configuration
public class DataSourceConfig {
#Bean("dataSource")
#Primary
#ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create()
.type(DriverManagerDataSource.class)
.build();
}
#Bean("secondDataSource")
#ConfigurationProperties(prefix = "spring.seconddatasource")
public DataSource secondDataSource() {
return DataSourceBuilder.create()
.type(DriverManagerDataSource.class)
.build();
}
}
The application starts without errors but only the first database (or whichever datasource bean is marked as primary) gets created. Why not the second?
EDIT:
Once I create the second database manually, the application connects to both of them just fine. It is the automatic creation of the non-primary database only that is causing the problems.
Because you're using #ConfigurationProperties wrong. The annotation most certainly does not point a bean to the relevant configuration. The first DB gets created because, well, spring.datasource.* are actually standard Spring Boot properties.
If you wish to create two data sources, at the very least you'll need to set the appropriate properties (url, password) on the second one yourself. You may inject your custom properties (spring.seconddatasource.*) into the configuration class using #Value, of course.

Is it possible to have ressources in other project (Spring Boot)?

I want to work with MySQL 10 and Point for Geolocations.
My property for the dialect is :
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
On my Entity I use at the Moment:
#Column(name="location", columnDefinition = "POINT")
private org.springframework.data.geo.Point location;
The error message is:
com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Cannot get geometry object from data you send to the GEOMETRY field
I try to save it with a JpaRepository => save()
Is it possible with JPA?
spring.jpa.properties.hibernate.dialect=org.hibernate.spatial.dialect.mysql.MySQL56InnoDBSpatialDialect
spring.jpa.properties.hibernate.dialect=org.hibernate.spatial.dialect.h2geodb.GeoDBDialect
try with both versions of dialect not sure which one will suit your needs

JPA how to set column type to be BLOB for ElementCollection table

I'm using Spring Boot with Hibernate JPA with the following code in my entity class,
#ElementCollection
private Map<String, String> userFiles= new HashMap<>();
Where a collection table user_files is generated. However the default column type is VARCHAR(255) and sometimes user data can be longer than that. My question is how can I define this table to use BLOB or TEXT for column? I tried to throw in #Lob annotation directly there but does not work.
Have you tried the following?
#Column(columnDefinition="BLOB NOT NULL")
#MapKeyColumn(columnDefinition="BLOB NOT NULL")
See MapKeyColumn and Lob.

Grails creates old columns from in mysql database event on clean schema

During development I added some fields to some domain classes. Then after re-factoring these fields were removed.
But they continue to appear in database schema, even if I drop and recreate it between "grails run-app" invocations.
Can anyone give an idea of what's going on? There are no references to these fields any more in the app.
I'm running Grails 2.4.3 in dev mode with mysql 5.6
As a matter of fact this happens from time to time, i.e. sometimes after recreating the schema old fields are not created.
Here's my datasource config:
environments {
development {
dataSource {
driverClassName = "com.mysql.jdbc.Driver"
dialect = "com.dropbyke.mysql.dialect.MySQLUTF8InnoDBDialect"
dbCreate = "update"
url = "jdbc:mysql://localhost:3306/dropbike?useUnicode=true&characterEncoding=UTF-8"
username = "root"
password = "123"
}
}
UPD:
MySQLUTF8InnoDBDialect is custom dialect:
public class MySQLUTF8InnoDBDialect extends MySQL5InnoDBDialect {
#Override
public String getTableTypeString() {
return " ENGINE=InnoDB DEFAULT CHARSET=utf8";
}
}

Grails Scaffold - Generated MySQL Column Type for JodaTime DateTime field

I am new to Grails and am using Grails 2.1 with a MySQL 5.5 backend to build a sample project to learn.
I installed JodaTime 1.4 Plug-in and then ran grails install-joda-time-templates
However, when I declared a Domain Class field to be of type org.joda.time.DateTime, I got an error when attempting to save a new entry.
In order to isolate the problem, I created a simple Domain Class:
import org.joda.time.DateTime
class Project
{
String name
DateTime startDate
static constraints = {
name(blank: false, maxSize: 50)
startDate(validator: {return (it > new DateTime())})
}
}
The controller just sets scaffold to use the Domain Class.
My DataSource.groovy specifies dbCreate = "create-drop", as I am letting the tables get created by Grails.
Here is the error I get when I try to save:
Class:com.mysql.jdbc.MysqlDataTruncation
Message:Data truncation: Data too long for column 'start_date' at row 1
When I look at project.start_date column in the MySQL database that Grails created, the type is TINYBLOB.
My thought is that TINYBLOB may not be sufficient to store the data for a JodaTime DateTime field.
Does anyone know how I can make Grails create an appropriate type?
Thank you very much.
In your Config.groovy:
grails.gorm.default.mapping = {
"user-type" type: PersistentDateTime, class: DateTime
"user-type" type: PersistentLocalDate, class: LocalDate
}
And your mapping closure:
static mapping = {
startDate type: PersistentDateTime
}
Take a look at this post for more info, see if it helps.
What I did to make it work (Grails 2.1):
1) add to buildConfig:
compile "org.jadira.usertype:usertype.jodatime:1.9"
2) refresh the dependencies
3) run this command to add the user-type supported:
grails install-joda-time-gorm-mappings
4) finally in the domain class:
import org.jadira.usertype.dateandtime.joda.*
static mapping = {
column_name type: PersistentDateTime
}
Documentation was found here: persistence