How can I configure Grails id columns to use UUID on Oracle? - oracle

I'd like to use a 128-bit UUID rather than Long for the id field on all of my Grails domains. I'd rather not have to specify all of the mapping information on every domain. Is there a simple way to achieve this in a generic/global way? I'm using Grails 2.3.x, the Hibernate 3.6.10.2 plugin, the Database Migration Plugin 1.3.8, and Oracle 11g (11.2.0.2.0).
There seem to be a number of questions related to this, but none provide complete, accurate, and up-to-date answers that actually work.
Related Questions
What's the best way to define custom id generation as default in Grails?
grails using uuid as id and mapping to to binary column
Configuring Grails/Hibernate/Postgres for UUID
Problems mapping UUID in JPA/hibernate
Custom 16 digit ID Generator in Grails Domain

Using UUID and RAW(16)
If you want to use a UUID in your Grails domain and a RAW(16) in your database, you'll need to add the following.
For every domain, specify the id field. Here's an example using ExampleDomain.groovy
class ExampleDomain {
UUID id
}
Add the following mapping to Config.groovy
grails.gorm.default.mapping = {
id(generator: "uuid2", type: "uuid-binary", length: 16)
}
For details on the three values I've selected, please see these links.
http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/mapping.html#d0e5294
http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/types.html#types-basic-value-uuid
How should I store a GUID in Oracle?
Add a custom dialect to your data source entry in Datasource.groovy. If you are using Hibernate 4.0.0.CR5 or higher, you can skip this step.
dataSource {
// Other configuration values removed for brevity
dialect = com.example.hibernate.dialect.BinaryAwareOracle10gDialect
}
Implement the custom dialect you referenced in step #3. Here is BinaryAwareOracle10gDialect implemented in Java. If you are using Hibernate 4.0.0.CR5 or higher, you can skip this step.
package com.example.hibernate.dialect;
import java.sql.Types;
import org.hibernate.dialect.Oracle10gDialect;
public class BinaryAwareOracle10gDialect extends Oracle10gDialect {
#Override
protected void registerLargeObjectTypeMappings() {
super.registerLargeObjectTypeMappings();
registerColumnType(Types.BINARY, 2000, "raw($l)");
registerColumnType(Types.BINARY, "long raw");
}
}
For more information about this change, please see the related Hibernate defect https://hibernate.atlassian.net/browse/HHH-6188.
Using UUID and VARCHAR2(36)
If you want to use a UUID in your Grails domain and a VARCHAR2(36) in your database, you'll need to add the following.
For every domain, specify the id field. Here's an example using ExampleDomain.groovy.
class ExampleDomain {
UUID id
}
Add the following mapping to Config.groovy
grails.gorm.default.mapping = {
id(generator: "uuid2", type: "uuid-char", length: 36)
}
For details on the three values, please see the links in step #2 from the previous section.

I think there is a easy way:
String id = UUID.randomUUID().toString()
static mapping = {
id generator:'assigned'
}

Related

snake case for column names in phantom-dsl

Im trying to use this library for an existing application that already have records in cassandra and it table columns are written in snake case. Is there a way to have my phantom model objects in snake case.
Just override column name:
abstract class User extends Table[...] {
object lastName extends StringColumn {
override val name: String = "last_name"
}
}
Have a look here, at the official documentation.
import com.outworkers.phantom.NamingStrategy.SnakeCase.caseSensitive
import com.outworkers.phantom.NamingStrategy.SnakeCase.caseInsensitive
There is also a test suite that might be of help, but you need to import this in every file where you define tables. Tests are here.

Update by query multiple fields using Spring Data Elasticsearch?

I want to update all the documents that have for exemple the same name. I've seen in the elasticsearch documentation that I can use _update_by_query. So I tried to implement it in my repository like this:
#Query("{\"script\": { \"inline\": \"ctx._source.name = ?1\"; \"ctx._source.username = ?2\"; \"ctx._source.avatar = ?3\", \"lang\": \"painless\" }, \"query\": { \"match\": { \"name\" : \"?1\" }}")
List<User> update(String name, String username, String avatar);
But I get the following error:
nested exception is ElasticsearchStatusException[Elasticsearch exception [type=parsing_exception, reason=[script] query does not support [inline]]]
at org.springframework.kafka.listener.SeekUtils.seekOrRecover(SeekUtils.java:157) ~[spring-kafka-2.5.0.RELEASE.jar:2.5.0.RELEASE]
Edit 26.06.2020:
This answer is not correct, I added a correct on.
Old incorrect answer:
Seems strange to me, that this error comes from org.springframework.kafka.listener.SeekUtils.
To update using a script, you can use the update(UpdateQuery updateQuery, IndexCoordinates index) of a ElasticsearchOperations instance.
To have this in your Repository, you will need to create a repository cusomization like it is described here. In the implementation, autowire a ElasticsearchOperations instance. In this custom repository interface, you define the method
List<User> update(String name, String username, String avatar);
In the implementation, build up a UpdateQuery object with the script and the other information and pass this to the ElasticsearchOperations instance.
After checking the code of Spring Data Elasticsearch, I need to withdraw what I wrote in the first answer:
Currently Spring Data Elasticsearch does not support update by query. It is only possible to update entities with a know id either in a single operation or in a batch update.
I created an issue in Jira to add support for that.

Spring Data Rest Mongo - how to create a DBRef using an id instead of a URI?

I have the following entity, that references another entity.
class Foo {
String id;
String name supplierName;
**#DBRef** TemplateSchema templateSchema;
...
}
I want to be able to use the following JSON (or similar) to create a new entity.
{
"supplierName": "Stormkind",
"templateSchema": "572878138b749120341e6cbf"
}
...but it looks like Spring forces you to use a URI like this:
{
"supplierName": "Stormkind",
"templateSchema": "/template-schema/572878138b749120341e6cbf"
}
Is there a way to create the DBRef by posting an ID instead of a URI?
Thanks!
In REST, the only form of ID's that exist are URIs (hence the name Unique Resource Identifier). Something like 572878138b749120341e6cbf does not identify a resource, /template-schema/572878138b749120341e6cbf does.
On the HTTP level, entities do not exist, only resources identified by URIs. That's why Spring Data REST expects you to use URIs as identifiers.

grails 3 ConstraintException

I'm using grails 3.02 and all was fine, but since I moved several domain classes from another grails project I started seeing this error when I do start integration tests:
grails.validation.exceptions.ConstraintException: Exception thrown applying constraint [unique] to class [class com.mypackage.Individual] for value [true]: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext#6397593b has not been refreshed yet
The domain class code:
class Individual {
String institutionId
String email
static mapping = {
table 'db.individual'
id generator: 'sequence', params: [sequence: 'db.individual_id_sequence']
institutionId index: 'db.individual_institution_id_idx'
email index: 'db.individual_email_idx'
}
static constraints = {
institutionId(blank: false)
email(unique: true)
}
}
The strange thing is: this code is working in another project but does not want to work in this one, in where I moved it to. I compared configs(application.yml and application.groovy and build.gradle) - but all is basically the same.
Any help, grails gurus?
I think I have found why I had this exception. It was not related to constrains at all.
I just had some other fields in my domain class which used to be calculated, so it was unmapped field. But grails used to try to map this field into a real database column. Once I've defined my own getter(in which the field initializes) for this calculated field all became fine.
But the grails exception btw is stupid and disorienting - it does not describe the root cause at all.

Grails: domain properties are mandatory by default and Id is not generated

I am new to Grails. I installed Grails 2.4.4 version and Spring Tool Suite.
I created Grails project and domain ,controller classes. But i am getting all the fields as mandatory by default and "id" is not generated. Need some help.
Domain Class:
package org.example.pomorodo
class Task {
String summary
String details
Date dateCreated
Date deadLine
Long timeSpent=0L
static constraints = {
}
}
Controller Class:
package org.example.pomorodo
class TaskController {
static scaffold =Task
}
Do you mean you can't access the "id" property after saving your domain object with GORM? Or just that the generated code doesn't have an "id" property explicitly defined? If it's the latter, don't worry. The "id" property is automatically injected by metaprogramming black-magic by the framework. If it's the former, something else is wrong, as you should definitely have a valid "id" after saving a domain object.
On the mandatory fields: Use the constraints block to toggle fields to nullable = true. Example:
package org.example.pomorodo
class Task {
String summary
String details
Date dateCreated
Date deadLine
Long timeSpent=0L
static constraints = {
summary(nullable:true)
details(nullable:true)
}
}
You can also modify default constraints globally. See the constraints documentation for more details.
Recently I got a query regarding mapping a database table which do not have any id and version. For example the table have two varchar fields username and password nothing more than that.
Although it was something strange for me that table doesn’t have the id field. The good thing is that the username is a primary key in the table and this is not auto incremented user want to create it by his own method.
The good thing about grails is, in most of the cases you get your answer in the docs http://grails.org/doc/latest/ . So in this case we just need to change the id field in grails domain like this
class Test {
String username
String password
static mapping = {
id name: 'username'
version false
id generator: 'assigned'
}
static constraints = {
username(nullable: true)
}
}

Resources