Grails Domain Object (GORM) inheritance - grails

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

Related

Grails 3 domain class composition

With Grails 3.2.5, hibernate 5.1.2 core.
I have a legacy database that has several clobs in a table. In order to avoid eager fetching, in earlier versions of Grails I defined a domain class that contained only those clobs in order to make them accessed via an (apparent) association which could then be lazily fetched. A sketch of the setup:
class Comment {
String someField // eager
CommentText cmntText // lazy
static mapping = {
id column: 'COMMENT_ID', generator:'sequence', params:[sequence:'cmnt_seq']
}
In a separate domain class file:
class CommentText {
String userComment
static mapping = {
table 'COMMENT'
id generator:'assigned'
userComment sqlType:'clob'
}
As noted, clob column 'user_comment' exists in the single table 'COMMENT'.
In 3.2.5, when doing this I get an error that column 'comment_text_id' is not defined in table 'comment'. This didn't use to be the case, nor should the field have to exist.
On a similar note, in another case I define a composite domain class (a class defined in the same file as the actual domain class). In this case too I get an error about a missing id:
class A {
B b
}
class B {
String someField
}
In this case I get an error saying that field b_id is not in table 'A'. But - it's supposed to be embedded composition, it should not be there.
I'm building within Intellij if that is relevant.
With GORM 6.1 this is now possible with a single domain class
import grails.gorm.hibernate.annotation.ManagedEntity
import static grails.gorm.hibernate.mapping.MappingBuilder.*
#ManagedEntity
class Comment {
String someField
String userComment
static constraints = {
}
static final mapping = orm {
id {
generator("sequence")
params(sequence:'cmnt_seq')
}
userComment = property {
lazy(true)
column {
sqlType 'clob'
}
}
}
}

Grails: Multiple Relationships between same two Objects

How do I define a relationship like the following:
A person can belong to many projects. A person can be the technical contact for a project or, they can be the business contact for a project or they can be both. If the person gets deleted the project doesn't get deleted. If a project gets deleted the person doesn't get deleted.
class Project {
String name
Person technicalContact
Person businessContact
static constraints = {
}
}
class Person {
String firstName
String lastName
String email
String phone
String department
static constraints = {
}
}
You can have 2 one-to-many in one table like this
class Project {
String name
}
class Person {
String firstName
String lastName
String email
String phone
String department
static hasMany = [technicalContactForProjects: Project ,
businessContactForProjects: Project
]
}
Grails will automatically make 2 relation table from that 2 hasMany, so you can delete its relation without delete the actual person or project.

Grails hasMany error creating beans

I'm creating a (theoretically) simple hasMany relationship within a domain class. I have two tables with a foreign key relationship between the two. Table 1's domain object is as follows:
Functionality{
String id
static hasMany = [functionalityControllers:FunctionalityController]
static mapping =
{
table 'schema.functionality'
id column:'FUNCTIONALITY_NAME', type:'string', generator:'assigned'
version false
}
}
and domain object 2
FunctionalityController
{
String id
String functionalityName
String controllerName
static mapping =
{
table 'schema.functionality_controller'
id column:'id', type:'string', generator:'assigned'
version:false
}
}
The issue I am having is that when I have the hasMany line inside of the Functionality domain object, the app won't start (both the app and the integration tests). The error is org.springframework.beans.factory.BeanCreationException leading to Invocation of init method failed; nested exception is java.lang.NullPointerException.
Any help would be appreciated.
UPDATE:
*Working Domains*:
class Functionality {
String id
static hasMany = [functionalityConts:FunctionalityCont]
static mapping =
{
table 'schema.functionality'
id column:'FUNCTIONALITY_NAME', type: 'string', generator: 'assigned'
functionalityConts( column:'functionality_name')
version false;
}
}
and
class FunctionalityCont {
String id
String functionalityName
String controllerName
static belongsTo = [functionality: Functionality]
static contraints = {
}
static mapping =
{
table 'schema.functionality_controller'
id column:'id', type: 'string', generator: 'assigned'
functionality(column:'FUNCTIONALITY_NAME')
version false;
}
}
Well 2 things...
1.I'm not sure but I guess that your domain class with the prefix 'Controller' maybe is the responsible, this is because grails is convention over configuration and by convention the controller class ends with Controller prefix and are in the controller folder, in this case is a lil' confusing
2.In GORM and in this case the relationship between objects can be unidirectional or bidirectional, is your decision to choose one, but in both cases there are different implementations, the class Functionality(btw is missing the 'class' word) has the right relationship to FunctionalityController through hasMany, but FunctionalityController doesn't knows about the relationship, so you can implement:
// For unidirectional
static belongsTo = Functionality
// For bidirectional
static belongsTo = [functionality:Functionality]
// Or put an instance of Functionality in your domain class,
// not common, and you manage the relationship
Functionality functionality
So check it out and tell us pls...
Regards
Try adding
static belongsTo = [functionality: Functionality]
to your FunctionalityController class. I suspect there is more to your error than what you've shown, but generally a hasMany needs an owning side to it. Since that is where the foreign key actually lives.

Creating domain classes with foreign key constraints in groovy

Hi I am trying to create a domain class with foreign key constraint to another existing domain class
New domain class is ArEntitlement defined as below
package ars
import gra.Resources
class ArEntitlement {
long id
String entitlementname
String entitlementdesc
String entitlementcomm
Integer departmentid
Resources resource
Integer version
static belongsto =[resource : Resources]
static mapping={
table 'ar_entitlement'
id(generator:'increment')
column{
id(column:'id')
}
}
}
Resource domain class is defined as follows (it was created before)
package gra
import com.gra.transaction.UserTransaction
class Resources {
Long id=1
String resourceName
Double resourceType
String resourceOwner
Double riskScore
Integer decommissioned
String resourceClass
Long resourceSegment
String targetIp
String resCriticality
Long resourceGroup
Integer disabled
static hasMany=[userTransactions:UserTransaction]
static mapping = {
table 'resource'
version false
id(generator:'increment')
column{
id(column:'id') }
}
static constraints=
{
resourceName(nullable:true,blank:false)
resourceType(nullable:true,blank:false)
resourceOwner(nullable:true,blank:false)
riskScore(nullable:false,blank:false)
decommissioned(nullable:false,blank:false)
resourceClass(nullable:false,blank:false)
resourceSegment(nullable:false,blank:false)
targetIp(nullable:false,blank:false)
resCriticality(nullable:true,blank:false)
resourceGroup(nullable:false,blank:false)
disabled(nullable:false,blank:false)
}
}
The resulting tables created dont have a foreign key mapping of ar_entitlement table to resource table, it does create a column called 'resource_id' but without foreign key constraint.
I need it to be pointing to id column of resource table
I tried several options, not having the belongsto specifier, using hasOne (in both domain classes) but not getting required foreign key relationship.
Any Idea what the issue is here?
log error i get is
2011-12-21 19:50:17,258 [main] ERROR hbm2ddl.SchemaUpdate - Unsuccessful: alter table ar_entitlement add index FKDCD6161FEFD54E5E (resourceid_id), add constraint FKDCD6161FEFD54E5E foreign key (resourceid_id) references resource (id)
Remove 'Resources resource' row from ArEntitlement.
static belongsTo = [resource : Resources]
Should cover that and having it defined twice might be the issue. Also you shouldn't need to specify the table names, the id generator or id column as it appears you are using the GORM defaults. Try removing these as well.
Here is the modified code...
package ars
import gra.Resources
class ArEntitlement {
String entitlementname
String entitlementdesc
String entitlementcomm
Integer departmentid
Integer version
static belongsTo = [resource : Resources]
static mapping = {
}
}

Grails - How to implement a foreign key relationship not using an id column?

Have been trying to look for an answer for hours, but have so far not managed to come up with an adequate solution, so I'm hoping someone here might have some more experience with Grails, and implementing custom relationships in it.
My problem is that I have two classes:
Company
OrderConfig
OrderConfig contains two references to Company. 1 for a consignee, 1 for a shipper. I implemented the relationship (see below), and everything looks dandy, with my order_config table containing both a consignee_company_id column and a shipper_company_id column.
However, I do not want or need a company_id column at all. I would prefer using the CompanyName as the identifying column. How can I prevent Grails from automatically adding the id column to the company table, and instead use the companyName column as the primary key, thus ensuring my order_config table will be generated containing the companyName and not the company_id?
I tried embedding the company in the orderconfig class, and wrestled with all kinds of other options including the mappings, however I ran into trouble with each and every one of them.
Thanks in advance!
My code so far:
class OrderConfig {
static hasMany = [consignee:Company, shipper:Company]
String toString() {
return "${consignee}"
}
static constraints = {
consignee (blank:false, maxSize:10)
shipper (blank:false, maxSize:10)
}
Company consignee
Company shipper
}
class Company {
String toString() {
return "${companyName}"
}
static constraints = {
companyName(blank:false, maxSize:10)
companyAddress1(blank:false, maxSize:40)
companyAddress2(blank:false, maxSize:40)
companyAddress3(blank:false, maxSize:40)
companyAddress4(blank:false, maxSize:40)
companyZipCode(blank:false, maxSize:36)
companyCountry(blank:false, maxSize:36)
}
String companyName
String companyAddress1
String companyAddress2
String companyAddress3
String companyAddress4
String companyZipCode
String companyCountry
}
You need to look at the advanced GORM config options in the documentation, in section 5.5.2.1
There is an example
class Person {
String firstName
static hasMany = [addresses:Address]
static mapping = {
table 'people'
firstName column:'First_Name'
addresses joinTable:[name:'Person_Addresses', key:'Person_Id', column:'Address_Id']
}
}
there you can see how they are specifying the key and column name on which to do the stuff.
Edit -- I reread your question: if you are asking how to change it so Company has an assigned id, you might be able to do something like this example
static mapping = {
id generator:'assigned', column:'column_name',name:'propertyName'
}
where more options are available here: http://www.grails.org/doc/1.3.x/ref/Database%20Mapping/id.html

Resources