How can I retrieve a list of Grails composite id properties?
I have tried the following but the id property is returning a Long:
Domain
class Domain implements Serializable {
String field1
String field2
static mapping = {
id composite: ['field1', 'field2']
}
}
Test
def d = DefaultGrailsDomainClass(Domain.class)
assert(d.identifier.type == java.lang.Long)
After deep diving GORM I found the solution:
GrailsDomainBinder.getMapping(Domain).identity.propertyNames
Related
I need to map Domain classes and subclasses of a legacy database.
The model thath I need to recreate with Grails is to this tables:
Tables structure
CARD_PAYMET and CHEQUE_PAYMENT is subclasses of PAYMENT and share a composite key of two field: OrderId and PaymentId.
I try some ex scenarios, but I can´t arrive to solution. None of then recreate the same model data, and I can´t change this model.
Can any one help me?
Thanks.
Your database looks like a good fit for table-per-subclass inheritance. First, since you're using a composite primary key, your domain classes need to implement the Serializable interface. Then it's a matter of mapping each table column to a property.
import groovy.transform.EqualsAndHashCode
#EqualsAndHashCode(includes=['orderId', 'paymentId'])
class Payment implements Serializable {
int orderId
int paymentId
float amount
static mapping = {
version false
tablePerHierarchy false
id composite: ['orderId', 'paymentId']
orderId column: 'OrderId'
paymentId column: 'PaymentId'
/* Assuming case-insensitive db, so I left out 'Amount'. */
}
}
class CardPayment extends Payment {
String cardType
static mapping = {
version false
cardType column: 'CardType'
}
}
class ChequePayment extends Payment {
int checkNumber
static mapping = {
version false
checkNumber column: 'CheckNumber'
}
}
Note: In this example I used Groovy's EqualsAndHashCode AST transformation to implement Serializable.
With the domain classes in place you'll be able to do GORM polymorphic queries:
def payments = Payment.list() // All Payments (Payment, CardPayment, and ChequePayment).
def cardPayments = CardPayment.list() // Only CardPayments.
...
def nicePayments = Payment.where { amount > 1000 }.list()
I have 4 Grails domain classes ( Domain1, Domain2, Domain3, Domain4). These domain objects map to legacy tables with exactly same set of columns. To be more precise, all of these tables have personFirstName, personLastName and personPhoneNumber columns.
The only thing different between these 4 domain classes is the table name they refer to.
Instead of copy/pasting same piece of code in four different places and just modifying this:
static mapping = {
table name:"legacy_table_name_A" <====== (only difference)
firstName column: "personFirstName"
lastName column: "personLastName"
phoneNumber column:"personPhoneNumber"
}
I was wondering if there is a way to do this all in one abstract class called MyAbstractDomainClass and have my Domain1, Domain2... extend it like this:
class MyAbstractDomainClass {
String firstName
String lastName
String phoneNumber
static mapping = {
firstName column: "personFirstName"
lastName column: "personLastName"
phoneNumber column:"personPhoneNumber"
}
}
class Domain1 extends MyAbstractDomainClass {
static mapping = {
}
}
How do I implement the static mapping for each Domain classes to have a different table name?
I am using Grails 2.4.2
I have two classes: sample, and parameter. I also have a sample_sample_parameter lookup table which exists to hold the sample id and the parameter id. This is mapped in my grails app.
I was able to write an sql query that works in squirrel:
select s.* from sample s, sample_sample_parameters sp where s.id = sp.sample_id and sp.sample_parameter_id = 41
where 41 would be replaced with the parameter.id variable passed from the gsp page to the action. I have also tried to make it work with executeQuery but it tells me that sample is not mapped.
How do I turn this query into a gorm recognizable form?
class Sample {
Date collectionDate // date the sample was collected
Date sampleReceivedDate // date the sample arrived on site
Date dateCreated
String sampleComments // details about the sample
String labAccessionID // internal reference
String sampleGender // is it from a male or female?
String sampleAge // the age of the animal the sample was taken from
String sampleBreed // the breed of animal
String sampleNameID // patient name
String filepath
String enteredby
String sg
String mosm
static searchable = true
static hasMany =[sampleParameters:SampleParameter, ficsruns:Ficsrun]//[tags:Tag]// a Sample can have many parameters
/* mappedBy allows two tables share a common table. It creates two join tables, one for each.
* SampleParameter is the table being shared by Sample and SampleType tables */
static mappedBy=[sampleParameters:"samples"]//[tags:"domainClass1s"]/*http://www.van-porten.de/2010/09/multiple-many-to-many-in-grails/*/
static belongsTo = [sampleType:SampleType, labFinding:LabFinding, sampleSource:SampleSource, species:SpeciesList] // creates dependencies
static constraints = {
sampleType(blank:false)
sampleNameID(blank:false)
collectionDate(blank:false)
sampleReceivedDate(blank:false)
sampleComments(nullable:true, maxSize:1000)
labAccessionID(nullable:true)
sampleGender(blank:false, inList:["M","F","NM","SF", "UNK"])
sampleAge(nullable: true)
sampleBreed(nullable:true)
sampleSource(blank:false)
species(blank:false)
labFinding(nullable:true)
filepath(nullable:true)
enteredby(nullable:true)
sg(nullable:true)
mosm(nullable:true)
dateCreated()
}
/* This section is for static mapping to the hematology database*/
static mapping = {
version false
id generator:'sequence', params:[sequence:'SHARED_SEQ']
}
String toString(){
"${sampleNameID}"
}
}
class SampleParameter implements Comparable{
String name
String value
static hasMany = [
samples:Sample, //domainClass1s: DomainClass1,
sampleTypes:SampleType //domainClass2s: DomainClass2
]
static mapping = {
version false
id generator:'sequence', params:[sequence:'SHARED_SEQ']
}
static mappedBy = [samples:"sampleParameters",sampleTypes:"sampleParameters"]//[domainClass1s: "tags", domainClass2s: "tags"]
static belongsTo =[Sample,SampleType] //[DomainClass1, DomainClass2]
static constraints = {
name(blank:false)
//value()
//value(unique:true)
value (unique: 'name')
}
#Override public String toString() {
return name + " " + value
}
#Override
public int compareTo(Object o) {
if (o == null || this == null) {
return 0;
} else {
return value.compareTo(o.value)
}
}
}
As a first suggestion, when you have the paramter's id, do the following.
Parameter p = Parameter.get(params.id) // or wherever your id is stored
List<Sample> samples = Sample.findAllByParameter(p) // this assumes, the parameter property is actually named 'parameter'
Of course there is no error handling in place right now, but you'll get the idea.
Welcome to GORM, welcome to Grails.
The problem is that you're not using a HQL query in your executeQuery method. Instead you're using native sql. From the manual:
The executeQuery method allows the execution of arbitrary HQL queries.
Take a look at the specification to see ways of doing that. Which, by the way, are way easier than native sql.
List<Sample> samples = Sample.findAllBySampleParameter(SampleParameter.get(variable))
Give it a try?
class Ctr_country {
String ctr_name
String ctr_abrev
String toString(){
ctr_abrev
}
}
I am using SQLS Express as database. I want the primary key of this class (table) to be ctr_abrev.
a) How can i do so ?
static mapping = {
id generator:'assigned', name:'ctr_abrev'
}
Grails Docs GORM id
I have to implement map values in my Grails app.
I have a class that can contain 0..N OsmTags, and the key is unique.
In Java I would model this with a Map in each object, but I don't know how to map classes in Grails.
So I defined this class:
class OsmTag {
/** OSM tag name, e.g. natural */
String key
/** OSM tag value, e.g. park */
String value
static constraints = {
key blank:false, size:2..80,matches:/[\S]+/, unique:false
value blank:false, size:1..250,matches:/[\S]+/, unique:false
}
}
That works ok, but it's actually quite ugly because the tag key is not unique.
Is there a better way to model this issue?
Cheers
If your tags are simple strings, then you can use a map directly.
class Taggable {
Map tags // key : String, value : String
}
If I understand your question correctly, then you want to ensure that each tag is unique within a particular instance of the tagged entity?
Assume that the entity to which the tags are attached is named Taggable, then
you can enforce this requirement using a custom constraint:
class Taggable {
static hasMany = [ tags: OsmTag ]
}
class OsmTag {
static belongsTo = [ taggable: Taggable ]
/** OSM tag name, e.g. natural */
String key
/** OSM tag value, e.g. park */
String value
static constraints = {
key(blank:false, size:2..80,matches:/[\S]+/, unique:false,
validator: { val, obj ->
if (obj.taggable.tags.key.count(val > 1)) {
return false
}
}
)
value(blank:false, size:1..250,matches:/[\S]+/, unique:false)
}
}
If you're looking for a NoSQL solution, you could try using MongoDB with Grails. The most recent version (1.4) supports Geospatial indexing and querying.