Issue Details (XML | Word | Printable)

Key: GRAILS-1023
Type: Sub-task Sub-task
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Graeme Rocher
Reporter: Pablo Pazos Gutierrez
Votes: 4
Watchers: 3
Operations

If you were logged in you would be able to see more operations.
Grails
GRAILS-3396

Add persistence support to Collections and Maps of basic (no domain classes) types

Created: 04/Apr/07 08:04 AM   Updated: 29/Oct/08 11:34 AM
Component/s: Persistence
Affects Version/s: 0.5-RC1
Fix Version/s: 1.1-beta1

Time Tracking:
Not Specified


 Description  « Hide
I have to put a simple list of names as a domain class attribute, but a list of strings doesnt work, and I have to do a domain class to wrap strings in it to make it works. It'll fine if I cand do things like:

class XXXX {
List names = []
}

and the names on the list persists to the db without more work.

What I've tried to do is something like this:
class Pepe {
List names
static hasMany = [names: String]
}

thanks.



 All   Comments   Work Log   Change History      Sort Order: Ascending order - Click to sort in descending order
Alex Wei added a comment - 04/Apr/07 08:40 AM
First of all, it must be decided on how to store the collection of basic types in a relational database.

Option 1:
Use JDBC ARRAY type.

Option 2:
Use Java serialization to store the whole collection in a column of byte array. (BLOB or VARBINARY or LONGVARBINARY).

Option 3:
Use XML serialization to store the whole collection in a column of VARCHAR or LONGVARCHAR.

Option 4:
Store the collection in a separate table.

Option 5:
Hacks, such as comma-delimited String... What about having a comma in a String element? What about various types within one array?

As there are workarounds, I propose to lower the priority to 'Minor'.


Pablo Pazos Gutierrez added a comment - 04/Apr/07 09:18 AM
Hi, option 5 breaks database 1st normal form.

I think separating the tables is a good option. Maybe it's a good idea to set the table name to something that denotes that is a table of datavalues and not a mapping from a domain class, something like: string_collection_1234 or string_map_3214, and the mapping table of the domain class that has this attribute (collection or map of strings) reference to those table names, I'm only thinking about it, I dont know very much about how hibernate works.


Peter Ledbrook added a comment - 05/Apr/07 12:37 PM
Looks like Hibernate supports collections of basic types by creating a dedicated table. The mapping looks like this:
<set name="names" table="person_names">
    <key column="person_id"/>
    <element column="person_name" type="string"/>
</set>

More info here:

http://www.hibernate.org/hib_docs/v3/reference/en/html/collections.html#collections-ofvalues


Pam added a comment - 30/Apr/08 03:44 PM
Hi, I am also trying to do this, like this:

class NetworkOperator{ String name HashMap otherNames = new HashMap() static hasMany = [otherNames:String] }

I would expect this to work in a dedicated table, I will probably use Peter's Hibernate manual mapping for now. It would be very nice if grails could do this on it's own... Thanks!


Graeme Rocher added a comment - 29/Oct/08 11:01 AM - edited
GORM now supports basic collection types using a join table:
class Person {
    static hasMany = [nicknames:String]
}

Grails will map a new join table called "person_nicknames":

person_id string
1 "joejoe"
1 "yoyo"

You can change the mapping using the joinTable argument:

class Person {
    static hasMany = [nicknames:String]

    static mapping = {
       hasMany joinTable:[name:'bunch_o_nicknames', key:'person_id', column:'nickname', type:"text"]       
    } 
}

Graeme Rocher added a comment - 29/Oct/08 11:34 AM
minor edit made to description of fix