Find Object in Many-to-Many Szenario - Grails - grails

i got this situation:
- class user with hasMany Roles and belongsTo Roles
- class Role with hasMans User
how can i get the roles belongs to a user, object user is given,
how can i get objects in a many-to-many szanario?
findByX doesn't work, it's affect just one table, but i need a "find" or something else to find Object overall / over many tables.
can anyone help me? and excuse my no propper english^^

If you have a User class that looks like this:
class User {
String username
static hasMany = [roles: Role]
static belongsTo = Role
}
and a Role class that looks like this:
class Role {
String name
static hasMany = [users: User]
}
then your Role class has a collection of its Users - the hasMany defines that. The same goes for User and its Roles.
So if you have a user, the user's roles are just "user.roles":
def user = User.findByUsername('foo')
user.roles.each { role ->
println "User $user.username has role $role.name"
}
and you can do the same thing for role:
def role = Role.findByName('ROLE_ADMIN')
role.users.each { user ->
println "User $user.username has role $role.name"
}

Related

grails grom create criteria with many-to-many mapping

I have two domain classes: User and Book.
class Book implements Serializable{
String bookName
Timestamp createdDateTime
Blob file
static belongsTo = [User]
static hasMany = [user :User]
}
I am able to add user in book using addToUser() method.
But I am stuck in create criteria while applying filter in user.
def query = Book.createCriteria();
def results = query.list () {
eq("user",userObject) // not working since user field is a list of users.
order("createdDateTime", "desc")
}
Please help me with the correct way of filtering.
You need to join the user table first in a many-to-many relation. The criteria should look like:
Book.withCriteria {
user {
eq("id", userObject.id)
}
order("createdDateTime", "desc")
}
I'm not 100% sure how you're trying to model your domain but maybe you want a Book to have a single user? In which case you'd have the belongsTo relationship on Book e.g.
class Book {
String bookName
Timestamp createdDateTime
Blob file
static belongsTo = [user: User]
}
Then have the hasMany relationship on User e.g.
class User {
String name
static hasMany = [books: Book]
}
Then you can look Books up with criteria like:
def user = User.findByName( 'bob' )
def results = Book.createCriteria().list () {
eq( "user", user )
order( "createdDateTime", "desc" )
}

Grails GORM: Change foreign key column name

I'm trying to change the foreign key column name that is used in Visitor table for User's id. The column is named now user_id, I want to change that to who_id.
Minimal User Domain Class:
class User {
static hasMany = [
visitor: Visitor
]
String uid
...
}
Minimal Visitor Domain Class:
class Visitor {
static belongsTo = [user: User]
....
}
Question:
I've tried with mappedBy but with no success, is there another way to use a property from User as a foreign key in Visitor?
I think you want to use the mapping static block:
class Visitor {
static belongsTo = [user: User]
static mapping = { user column: 'who_id' }
}
You can mark the uid in User as the id (primary key). That will make it automatically the foreign key in the Visitors domain.
class User {
String uid
static mapping = {
id column: 'uid'
}
...

inheritance in Grails domain model

My Grails app's domain model has the following requirements:
a user belong to zero or one organisations
an organisation is either a charity or a company
charities and companies have some some common fields and also some (non-nullable) fields that are unique to each organisation type
I put the common organisation fields into an abstract Organisation class which Charity and Company both extend. I can't store this hierarchy in a single table because there are non-nullable fields that are specific to each organisation type. The relevant parts of the domain model are shown below:
class User {
String name
static belongsTo = [organization: Organization]
static constraints = {
organization nullable: true
}
}
abstract class Organization {
String name
static hasMany = [users: User]
static mapping = {
tablePerHierarchy false
}
}
class Charity extends Organization {
// charity-specific fields go here
}
class Company extends Organization {
// company-specific fields go here
}
When I look at the MySQL schema generated from this model, the inheritance relationship between organisation-company and organisation-charity seems to have been completely ignored. Although there is an organisation table with a name column, it has no primary-foreign key relationship with either company or charity
I see the same result as IanRoberts for both MySQL and H2. In other words: no join table generated, but the expected organization_id FK in the users table.
With "Table per subclass" mapping (tablePerHierarchy false), you end up with an implied one-to-one relationship in the database. Primary Keys for Charity and Company will have the same value as the PK for the parent Organization. The schema generated by GORM/Hibernate3 doesn't appear to enforce this with referential integrity constraints. It's pure Hibernate magic. A bit more detail here
Solved!
Add the class below to src/java (this class cannot be written in Groovy)
package org.example;
import org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsAnnotationConfiguration;
import org.hibernate.MappingException;
import org.hibernate.mapping.JoinedSubclass;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.RootClass;
import java.util.Iterator;
public class TablePerSubclassConfiguration extends GrailsAnnotationConfiguration {
private static final long serialVersionUID = 1;
private boolean alreadyProcessed = false;
#Override
protected void secondPassCompile() throws MappingException {
super.secondPassCompile();
if (alreadyProcessed) {
return;
}
for (PersistentClass persistentClass : classes.values()) {
if (persistentClass instanceof RootClass) {
RootClass rootClass = (RootClass) persistentClass;
if (rootClass.hasSubclasses()) {
Iterator subclasses = rootClass.getSubclassIterator();
while (subclasses.hasNext()) {
Object subclass = subclasses.next();
// This test ensures that foreign keys will only be created for subclasses that are
// mapped using "table per subclass"
if (subclass instanceof JoinedSubclass) {
JoinedSubclass joinedSubclass = (JoinedSubclass) subclass;
joinedSubclass.createForeignKey();
}
}
}
}
}
alreadyProcessed = true;
}
}
Then in DataSource.groovy set this as the configuration class
dataSource {
configClass = 'org.example.TablePerSubclassConfiguration'
pooled = true
driverClassName = "org.h2.Driver"
username = "sa"
password = ""
dbCreate = "update"
url = "jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000"
}
I've submitted a pull request to Grails that fixes this. The fix was be included in Grails 2.3.9.
ORM is not RDBS.
tablePerHierarchy false
so You Have three tables: Organization, Charity, Company. User belongs to only Organization (not Charity or Company). How are you going to get value of specific fields?
There is USER. We know ORGANIZATION, but we don't know Charity or Company. I think you underst...
I can suggest you three solutions:
1. tablePerHierarchy true (But you need to have nullable charity\Company -specific fields )
2.
class User {
static belongsTo = [charity: Charity, company: Company]
}
class Charity {
String name
static hasMany = [users: User]
// charity-specific fields go here
}
class Company {
String name
static hasMany = [users: User]
// company-specific fields go here
}
3.
class User {
static belongsTo = [organization: Organization]
}
class Organization {
String name
Charity charity //nullable
Company company //nullable
static hasMany = [users: User]
}
class Charity {
static belongsTo = [organization: Organization]
// charity-specific fields go here
}
class Company {
static belongsTo = [organization: Organization]
// company-specific fields go here
}

Parameter #1 is not set error

I got an error with grails query.
I had class User:
class User {
String username
String passwordHash
static hasMany = [roles: Role, permissions: String, clients: User, owners: User]
}
When i do query:
def addClient() {
def principal = SecurityUtils.subject?.principal
User currentUser = User.findByUsername(principal);
if (request.method == 'GET') {
User user = new User()
[client: currentUser, clientCount: User.countByOwners(currentUser)]
}
}
Grails say that:
Parameter "#1" is not set; SQL statement: select count(*) as y0_ from user this_ where this_.id=? [90012-164]
Why?
Looks like currentUser is null.
BTW, I wonder, why you count by owners, but specify a user as the owners? According to your hasMany definition, owners is a collection.

How to model a Friend - Friendship relationship in Grails

How would you model a friend - friendship relationship in Grails? Until now my User class had many followers
class User {
//Searchable plugin
static searchable = true
String userId
String password
boolean enabled = true
// For Spring Security plugin's user registration.
String email
String userRealName
boolean emailShow
Date dateCreated
Profile profile
static hasMany = [
posts : Post,
tags : Tag,
following : User,
authorities : Role,
notifications: Notification,
locations: Location,
incomingLocations:IncomingLocation,
]
static belongsTo = Role
static constraints = {
userId(blank: false, size:3..20, unique: true)
password(blank: false)
dateCreated()
profile(nullable: true)
userRealName(nullable: true, blank: true)
email(nullable: true, blank: true)
}
static mapping = {
profile lazy:false
}
}
But I would like to change the following:User for something like friendships:Friendship and create a Friendship class as following:
class Friendship {
static belongsTo= [user:User]
User friend2
boolean areFriends
}
Is this an ideal implementation?
How would you implement the handshake (accept/reject a pending friendship)?
You might not need to model Friendship directly. You can just have a hasMany relationship that relates the Users as friends. You don't create that relationship until someone accepts a FriendRequest. If they no longer want to be friends, then just remove the relationship between the 2 Users.
class User {
static hasMany = [friends:User]
}
class FriendRequest {
User fromUser
User toUser
}
That way Friendship doesn't have to do 2 things (relate users and track statuses). And friends becomes a natural object relationship which can make some things like optimizing fetching a bit easier.

Resources