ivanhoe
ivanhoe

Reputation: 111

Modelling a collection of name-value pairs in Grails/GORM

In my Grails app, I have a domain class with a property of type Map which will be a collection of name-value pairs (all names and values are strings)

class OauthProfile {
    String name
    // other properties omitted
    Map claims
}

When I look at the tables generated for this model they look like so:

mysql> describe oauth_profile;
+--------------+--------------+------+-----+---------+----------------+
| Field        | Type         | Null | Key | Default | Extra          |
+--------------+--------------+------+-----+---------+----------------+
| id           | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| version      | bigint(20)   | NO   |     | NULL    |                |
| name         | varchar(255) | NO   |     | NULL    |                |
+--------------+--------------+------+-----+---------+----------------+

mysql> describe oauth_profile_claims;
+------------+--------------+------+-----+---------+-------+
| Field      | Type         | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+-------+
| claims     | bigint(20)   | YES  |     | NULL    |       |
| claims_idx | varchar(255) | YES  |     | NULL    |       |
| claims_elt | varchar(255) | NO   |     | NULL    |       |
+------------+--------------+------+-----+---------+-------+

A problem with this schema is that at the DB-level there's no relationship between oauth_profile and oauth_profile_claims which means that it's possible to delete a row in oauth_profile without also deleting the associated rows in oauth_profile_claims.

Is there a way to model claims such that there is an explicit relationship between the two tables?

Upvotes: 0

Views: 99

Answers (2)

Frederic Henri
Frederic Henri

Reputation: 53713

I did not try with Map field but it works for object. you could use embedded property

class OauthProfile {
    String name
    // other properties omitted
    Map claims

    static embedded = ['claims'];
}

(again, not tested but worth trying)

Upvotes: 0

Mario David
Mario David

Reputation: 1615

What you can do is to create a explicit domain type and do a hasMany <--> belongsTo association like this:

class OauthProfile {
    String name
    static hasMany = [claims: OauthProfileClaim]
}

class OauthProfileClaim {
    String name
    String value
    static belongsTo = [oauthProfile: OauthProfile]
}

which lets you define your cascase behavior like any other gorm relationship (see docs). In the default behavior with a hasMany <--> belongsTo relationship you'll get a save update delete behavior as it says in the docs:

The default cascading behaviour is to cascade saves and updates, but not deletes unless a belongsTo is also specified:

Upvotes: 1

Related Questions