Mapping a uni-directional 1:M - grails

I have a a uni-directional 1:M.
A User can have many Carts. Before getting into a debate about ah this should be bidirectional, just assume I have to make uni-directional.
class User {
}
class Cart {
static belongsTo = [user: User]
static mapping = {
user joinTable: [name: 'cart_user']
}
}
I get:
org.hibernate.HibernateException: Missing column: user_id
Any ideas?

You are missing static hasMany = [carts:Cart]?
So try this (uni-directional):
class User {
static hasMany = [carts:Cart]
}
class Cart {
static belongsTo = [user: User]
}
update:
To make it bidirectional
class User {
static hasMany = [carts:Cart]
}
class Cart {
User user
static belongsTo = [user: User]
}

Related

dynamic fnder findAllBy getting null value from join table in many to many relationship using grails

I have 3 domain as Subscriber, Role and a join table as SubscriberRole for many to many relationship. Dynamic finder findAllBy getting null value from SubscriberRole domain.
Subscriber.groovy:
class Subscriber extends PartyRole{
Date dateCreated
Date lastUpdated
List<Contact> contacts = new ArrayList<Contact>();
static belongsTo = [ customer: Customer]
static hasMany = [seats: Seat, ownedEnquiries: Enquiry,enquiresSharedWith: SharedEnquiry, enquiriesSharedBy: SharedEnquiry ,
managedTeams: Team , memberships: Membership, contacts: Contact , sharedByContacts: SharedContact, sharedWithContacts: SharedContact,
vContacts: VContact, partOf: VContact, sharedbyVContacts: SharedVcontact, sharedWithVcontacts: SharedVcontact, tokens : Token,
notifications: Notification, discussions: Discussion]
static mappedBy = [ managedTeams : "manager" , enquiresSharedWith: "sharedWith" , enquiriesSharedBy: "sharedBy" ,
sharedByContacts : "sharedBy" , sharedWithContacts : "sharedWith" ,
vContacts: "forSubscriber" , partOf :"ofContact",
sharedbyVContacts: "sharedby" , sharedWithVcontacts :"sharedWith"
]
StatusEnum status
static constraints = {
contacts nullable: true
notifications nullable : true
}
Set<Role> getAuthorities() {
SubscriberRole.findAllBySubscriber(this).collect { it.role } as Set
}
public Subscriber(){
contacts = LazyList.decorate(contacts, FactoryUtils.instantiateFactory(Contact.class))
}
}
SubscriberRole.groovy:Domain
import org.apache.commons.lang.builder.HashCodeBuilder
class SubscriberRole implements Serializable {
Subscriber subscriber
Role role
Date dateCreated
Date lastUpdated
boolean equals(other) {
if (!(other instanceof SubscriberRole)) {
return false
}
other.subscriber?.id == subscriber?.id &&
other.role?.id == role?.id
}
int hashCode() {
def builder = new HashCodeBuilder()
if (subscriber) builder.append(subscriber.id)
if (role) builder.append(role.id)
builder.toHashCode()
}
static SubscriberRole get(long subscriberId, long roleId) {
find 'from SubscriberRole where subscriber.id=:subscriberId and role.id=:roleId',
[subscriberId: subscriberId, roleId: roleId]
}
static SubscriberRole create(Subscriber subscriber, Role role, boolean flush = false) {
new SubscriberRole(subscriber: subscriber, role: role).save(flush: flush, insert: true)
}
static boolean remove(Subscriber subscriber, Role role, boolean flush = false) {
SubscriberRole instance = SubscriberRole.findBySubscriberAndRole(subscriber, role)
if (!instance) {
return false
}
instance.delete(flush: flush)
true
}
static void removeAll(Subscriber subscriber) {
executeUpdate 'DELETE FROM SubscriberRole WHERE subscriber=:subscriber', [subscriber: subscriber]
}
static void removeAll(Role role) {
executeUpdate 'DELETE FROM SubscriberRole WHERE role=:role', [role: role]
}
static mapping = {
id composite: ['role', 'subscriber']
version false
}
}
Role.groovy domain:
package com.vproc.member
import java.util.Date;
class Role {
String authority
Date dateCreated
Date lastUpdated
static mapping = {
cache true
}
static constraints = {
authority blank: false, unique: true
}
}
As you can see from image, subscriber_role has 3 entries but when I try with findAllBySubscriber, it gives me null value. Any idea,why this is happening?
Problem:. When I fetch data from SubscriberRole table using**
Subscriber subscriber = Subscriber.get(params.id)
def subscriberRole = SubscriberRole.findAllBySubscriber(subscriber)
I am getting NULL [com.vproc.member.SubscriberRole : null] though SubscriberRole table has entries in db.
Is there anything wrong with above dynamic finder.
It's showing you in that format ([com.vproc.member.SubscriberRole : null]). that null must be because you have composite key on SubscriberRole.
But you are getting proper data as needed.
For representation you could add nice toString to your SubscriberRole, like,
public String toString()
{
return "${subscriber} :: ${role}"
}

GORM 'where criteria' with multiple many-to-many associations

Assuming you have three domain objs defined as such:
class Author {
String name
static hasMany = [books: Book]
}
class Book {
String name
static belongsTo = [author: Author]
static hasMany = [words: Word]
}
class Word {
String text
Set<Author> getAuthors() {
// This throws GenericJDBCException:
Author.where {
books.words == this
}
}
}
Why does getAuthors() fail with ERROR spi.SqlExceptionHelper - Parameter "#1" is not set; but works fine if rewritten using a Criteria:
public Set<Author> getAuthors() {
// This works as expected:
Author.withCriteria {
books {
words {
eq('id', this.id)
}
}
}
}
Do I have the syntax of the 'where query' wrong???
It seems like the criteria for your query is sort of misleading. books and words are both associations and you are expecting that words to be equal to single instance of the word object.
You can try this:
def getAuthors() {
Author.where {
books{
words {
id == this.id
}
}
}.list()
}

Grails Query with parent

If I have four domain classes like this:
class Branch {
String name
static hasMany = [users:Users]
static mappedBy = [users:'branch']
static mapping = {
id column: 'f_branch_id'
name column: 'f_name'
}
}
class Users {
String name
static hasMany = [account:Account]
static mappedBy = [account:'user']
static belongsTo= [branch:Branch, title:Title]
static mapping = {
id column: 'f_user_id',
name column: 'f_name',
branch column: 'k_branch_id'
}
}
class Account {
String username
static belongsTo = [user:Users]
static mapping = {
id column: 'f_account_id'
user column: 'f_user_id'
username column: 'f_username'
}
}
class JoinTable implements Serializable {
Account account
Role role
static mapping = {
id composite : ['role', 'account']
role column :'k_role_id'
account column :'k_account_id'
version false
}
}
How can i get branch from JoinTable using criteria query
i try this process but fail for alias problem
def criteria = JoinTable.createCriteria()
def list = criteria.list {
account {
user{
branch{
eq("id", "2")
}
}
}
}
Domains
class Branch {
String name
static hasMany = [users:Users]
static mapping = {
id column: 'f_branch_id'
name column: 'f_name'
}
}
class Title {
...
}
class Users {
String name
static hasMany = [account:Account]
static belongsTo= [branch:Branch, title:Title]
static mapping = {...}
}
class Account {
String username
static belongsTo = [user:Users]
static mapping = {...}
}
class Role {
...
}
class JoinTable implements Serializable {
Account account
Role role
static mapping = {
id composite : ['role', 'account']
role column :'k_role_id'
account column :'k_account_id'
version false
}
}
Test
#TestMixin(GrailsUnitTestMixin)
#Mock([Act, Branch, Title, Users, Account, Role, JoinTable])
class EaseTests {
void testCriteria(){
10.times{
def b = new Branch().save(validate:false, flush:true)
10.times{
def u = new Users(branch:b).save(validate:false, flush:true)
10.times{
def a = new Account(user:u).save(validate:false, flush:true)
def joinTableRow = new JoinTable(account: a).save(validate:false, flush:true)
}
}
}
def c = JoinTable.createCriteria()
def results = c{
account{
user {
branch{
idEq(2l)
}
}
}
}
assert results
}
}

Grails search two child objects

I have three domain objects
class OrgProfile {
String name
static mapping = {
discriminator column:'ORG_TYPE'
}
}
class Org extends OrgProfile {
static mapping = {
discriminator 'ORG'
}
}
class Jurisdiction extends OrgProfile {
String email
static mapping{
discriminator 'JURISDICTION'
}
}
I need to search by name and email to get all list of Org and Jurisdiction
so something like
def criteria = OrgProfile.createCriteria()
criteria.list{
or {
ilike("name", "%${token}%")
ilike("email", "%${token}%")
}
}
where token is a string. How can this be achieved?
Tried the code:
def criteria = OrgProfile.createCriteria()
def results = criteria.list{
or {
ilike("name", "%${token}%")
ilike("email", "%${token}%")
}
}
Results as expected.

Three domain classes relationship in GORM

is there a special way with gorm to map a three domain classes relationship like this:
1 person belongs to N companies with M given roles (one or more roles for a given company)
Thanks in advance.
look at http://www.grails.org/Many-to-Many+Mapping+without+Hibernate+XML (i think it's up to date).
be aware of: http://codedumpblog.blogspot.com/2010/02/grails-many-to-many-with-lists.html
the code below works for me using grails 1.2.0. but it seems like i had to do a lot of save()'s. don't forget to make the controllers and set scaffold=domain_class
package p
class Company {
String toString() { "$name"
}
static hasMany=[roles:Role]
static constraints = {
}
String name
}
package p
class Role {
String toString() { "$name"
}
static belongsTo=[company:Company]
static hasMany=[personRoleAssociations:PersonRoleAssociation]
static constraints = {
}
String name
}
package p
class Person {
String toString() { "$name"
}
static hasMany=[personRoleAssociations:PersonRoleAssociation]
static constraints = {
}
String name
}
package p
class PersonRoleAssociation {
String toString() { "${person.name} as ${role.name}"
}
static belongsTo=[person:Person,role:Role]
static constraints = {
}
}
import p.*
class BootStrap {
def init = { servletContext ->
Person dick=new Person(name:'dick')
Person jane=new Person(name:'jane')
dick.save()
jane.save()
Company ibm=new Company(name:'ibm')
ibm.save()
Role ibmManager=new Role(name:'ibmmanager')
Role ibmPeon=new Role(name:'ibmpeon')
ibm.addToRoles(ibmManager)
ibmManager.save()
ibm.addToRoles(ibmPeon)
ibmPeon.save()
ibm.save()
Company sun=new Company(name:'sun')
sun.save()
Role sunManager=new Role(name:'sunmanager')
Role sunPeon=new Role(name:'sunpeon')
sun.addToRoles(sunManager)
sunManager.save()
sun.addToRoles(sunPeon)
sunPeon.save()
sun.save()
PersonRoleAssociation dickManager=new PersonRoleAssociation()
dick.addToPersonRoleAssociations(dickManager)
ibmManager.addToPersonRoleAssociations(dickManager)
PersonRoleAssociation dickPeon=new PersonRoleAssociation()
dick.addToPersonRoleAssociations(dickPeon)
sunPeon.addToPersonRoleAssociations(dickPeon)
PersonRoleAssociation janeManager=new PersonRoleAssociation()
jane.addToPersonRoleAssociations(janeManager)
sunManager.addToPersonRoleAssociations(janeManager)
PersonRoleAssociation janePeon=new PersonRoleAssociation()
jane.addToPersonRoleAssociations(janePeon)
ibmPeon.addToPersonRoleAssociations(janePeon)
}
def destroy = {
}
}
I would try :
class Person {
String name
Set<Role> roles
Set<Company> companies
public String toString() {
return name + " roles : " + (roles.collect { it.name }).toString() + " - companies : " + (companies.collect { it.name }).toString()
}
static hasMany = [companies:Company, roles:Role]
static constraints = {
name (unique:true)
roles (nullable:true)
}
}
class Role {
String name
String toString() {
return name + " companies : " + (companies.collect { it.name }).toString()
}
static hasMany = [companies : Company]
static belongsTo = Company
static constraints = {
name (unique:true)
companies (nullable:false)
}
}
class Company {
String name
String toString() {
return name + " roles : " + (roles.collect { it.name }).toString()
}
static hasMany = [roles : Role]
static constraints = {
name (unique:true)
roles (nullable:true)
}
}
Didn't test though... I'd be interested in knowing if my solution has any problems and what they can be...

Resources