I have a column in my table called HDR_PROSHIP_REFERENCE_1 and a mapping in the domain of:
static mapping = {
table 'ORDER_LINE'
version false
id column: 'LINE_ID', insertable: 'false', updateable: 'false'
proshipReference1 column: 'HDR_PROSHIP_REFERENCE_1'
proshipReference2 column: 'HDR_PROSHIP_REFERENCE_2'
}
When GORM goes to build out a query against this, however, SQL throws an invalid identifier:
ORA-00904: "THIS_"."HDR_PROSHIP_REFERENCE2": invalid identifier
It looks like GORM, in its effort to camelcase columns by default, is not respecting the '_' before the numbers.
Is this a bug with GORM or am I not writing the mappings correctly?
Related
I am using the elasticsearch grails plugin for the first time, and when I set the config bulkIndexOnStartup = true, it indexed several of the domain classes correctly, but for a couple of others it seemed to only index one instance out of many, even though I saw 99 distinct instances in the database.
When I tried to specifically index the instances by calling
elasticSearchService.index( anInstance )
it would just delete the old entry and add a new one, so at the end there was still only one instance in elasticsearch. Is there an "indexAllDistinct" setting somewhere? How does it decide to add a new entry or replace an existing entry?
I also noticed that on the instances that were indexed correctly, the _id fields all had numeric values, but on the incorrectly indexed instance, the _id field was "null".
EDIT: I found that the incorrectly indexed classes have the "id" mapping name set to a different field. How can I tell elasticsearch that the "id" has a different name for these classes?
For grails domain classes that map the default "id" to another name, I had to add a transient "id" for elasticsearch. For example:
class LogEntry {
Integer logId // replaces default id
...
static mapping = {
id name: 'logId', column: 'LOG_ID'
...
}
static transients = ['id'] // for elasticsearch
def getId(){
return logId
}
}
I have a GORM query and I need to make it avoid a field which may be a empty string for legacy system questions.
Currently, my query is:
def things = Thing.withCriteria{
resultTransformer CriteriaSpecification.ALIAS_TO_ENTITY_MAP
createAlias 'factor', 'f'
eq 'active', true
isNotNull 'title' // this field may be an empty string
isNotNull 'content' // this field also may be an empty string
// <-- and here I'd like to include sth like isEmpty 'title'
not {
inList 'f.id', factors
}
projections{
property 'id' , 'id'
property 'f.name' , 'name'
property 'title' , 'title'
property 'content' , 'content'
property 'f.id' , 'factorId'
}
}
I didn't find any solution in the docs, but I have a feeling that this solution should be with pure SQL. Is it possible? Any suggestion?
Have you tried adding this statement to the criteria?
ne title, ""
Grails criteria relies on hibernate Restrictions, so everything supported by this can also be used in grails criteria.
Otherwise you could also use sql restrictions (see Using SQL Restrictions section):
sqlRestriction "char_length(title) > 0"
Keep in mind that title here refers to the real column name in the database. If you want to have a more reliable code, you can include a static mapping for the field (column name) in the model :
static mapping = {
title column: 'title'
}
In this way you should avoid errors from db specific naming behaviour (if any).
It seems that it is impossible with Grails to map a domain class to a database table that has is a foreign key column named 'interface'.
In my case there's a relationship with two tables INTERFACE and INTERFACE_DETAILS. They are legacy databases and column names can not be changed or added.
Put it simple INTERFACE_DETAILS has an FK column 'INTERFACE' referring to PK INTERFACE.ID
class Interface {
String id;
static mapping = {
table "INTERFACE"
version false
id generator: 'assigned'
id column: 'id', sqlType:"varchar2(20)"
}
class InterfaceDetails {
Interface iface;
static belongsTo = [iface: Interface]
static mapping = {
table "INTERFACE_DETAILS"
version false
id column: 'interface'
iface column: 'INTERFACE', sqlType:"varchar2(20)", insertable: false, updateable: false
}
}
I'm currently using H2 database. When I try to add a row to InterfaceDetails this error occurs:
Referential integrity constraint violation: "FK351396597E3917F9: PUBLIC.INTERFACE_DETAILS FOREIGN KEY(INTERFACE) REFERENCES PUBLIC.INTERFACE(ID)"; SQL statement:
insert into INTERFACE_DETAILS (interface) values (null) [23506-164]
I wonder why hibernate adds null for 'interface' value ?
I do have to have line : "id column: 'interface'" because in other case Hibernate will generate an extra column: "iface_id" and this is not suitable. Existing database columns can not be changed.
This is quite puzzling. Please tell me that Grails can handle this situation.
stripped down schema:
create table interface (id varchar2(20) not null,primary key (id));
create table interface_details (interface varchar2(20) not null, name varchar(255) not null, primary key (interface));
alter table interface_details add constraint FK_INTERFACE foreign key (interface) references interface;
I have a domain class called FoapRequest. I want one of the properties called "approver" to be a list of integers. Order matters, so I've defined the class as described by http://grails.org/doc/latest/guide/GORM.html#sets,ListsAndMaps as a list:
class FoapRequest {
Integer requester
Integer subject
List approver
static hasMany = [foap:FOAP, newFoap:NewFoap, approver:Integer]
...
Just for clarification, FOAP and NewFoap are two other domain objects.
I need to map this class to a particular table in the Oracle database, so I also specify a static mapping with a join table:
static mapping = {
table 'OUR_SCHEMA.FOAP_REQUEST_TABLE
id column : 'ID', generator:'sequence', params: [sequence:'OUR_SCHEMA.FOAP_REQUEST_SEQ']
requester column : 'REQUESTER'
subject column : 'SUBJECT'
approver indexColumn: [name: "APPROVER_IDX"], generator:'sequence', params: [sequence:'OUR_SCHEMA.APPROVER_SEQ'],
joinTable: [name:'OUR_SCHEMA.APPROVER_TABLE',
key: 'ASSOCIATED_REQUEST',
column: 'APPROVER_PIDM',
type: "integer"
]
However, when I try to create a new instance of the FoapRequest object, I get the following error:
Invalid column type
The console displays the following:
Error 2012-08-01 12:29:31,619 [http-bio-8080-exec-9] ERROR errors.GrailsExceptionResolver - SQLException occurred when processing request: [POST] /FOAPauth/foapRequest/saveFoapRequests - parameters:
I am certain that the issue lies with the jointable. The domain model didn't include the joinTable originally- approver was just an Integer type (I realized too late that I was going to need to track multiple approvers).
Here's the SQL for creating the APPROVERS table:
CREATE TABLE "OUR_SCHEMA"."APPROVER_TABLE"
(
"APPROVER_IDX" NUMBER(*,0) NOT NULL ENABLE,
"ASSOCIATED_REQUEST" NUMBER(*,0) NOT NULL ENABLE,
"APPROVER_PIDM" NUMBER(8),
);
I'd prefer to avoid creating an Approver domain class if at all possible, since all I really need to keep track of are the integer identifiers.
So, after much janking with join tables, I determined that the best way to deal with my needs was to simply create an Approver object in my domain model.
class Approver {
Integer pidm
String approvalDecision
Date lastUpdated
Date dateCreated
static belongsTo = [foap: FOAP]
}
To be honest, I'm not really sure why I was trying so hard to avoid this. Possibly because my DBAs use a version control system for table definitions that I find a hair annoying. :)
Regardless, a simple one-to-many relationship between domain classes met all my needs, no join table required.
For those who are still burning to know, I did manage to get a statically mapped join table working using a Map, which was more appropriate for my needs (though not as appropriate for them as a new domain class, and not nearly as simple).
I ended up doing it in a different domain object- FOAP instead of FoapRequest:
import java.util.Map
class FOAP {
...
Map approvalData
...
static mapping = {
table 'OURSCHEMA.FOAP_TABLE'
id column : 'ID', generator:'jpl.hibernate.util.TriggerAssignedIdentityGenerator'
fund column : 'FUND'
org column : 'ORG'
chartOfAccounts column : 'CHART_OF_ACCOUNTS'
permissionType column: 'PERMISSION_TYPE'
foapRequest column: 'REQUEST_ID'
version column : 'VERSION'
approvalData joinTable: [name:'OURSCHEMA.FOAP_APPROVERS',
key: 'FOAP'
]
}
For the table definition, I used the column names similar to those in my original question.
CREATE TABLE "OUR_SCHEMA"."APPROVER_TABLE"
(
"FOAP" NUMBER(*,0) NOT NULL ENABLE,
"APPROVER_IDX" VARCHAR2(255),
"APPROVER_DLT" NUMBER(8),
);
The IDX column was the map object's key, the DLT column its value. I'd recommend against this approach, for anyone who can avoid it. Creating a new domain object is much simpler.
I have a domain class having an Integer variable 'code'. my requirement is to make 'code', primary key column for that domain and also auto increment and to remove the default 'id' column from the table created for that doamin.thnks
use this :
static mapping = {
id name: 'code'
}
more informations here :
http://grails.org/doc/2.0.x/ref/Database%20Mapping/id.html
Domain classes in Grails by default dictate the way they are mapped to the database using sensible defaults. You can customize these with the ORM Mapping DSL.
Customizes the way the identifier for a domain class is generated with id.
See the Grails documentation for id.
static mapping = {
id column: 'code', type: 'integer'
}