Saving Nested Domain Objects in Grails - grails

I UPDATE THE ISSUE BELOW
I am trying to save a series of nested Domain Objects in Grails and I running into issues with the syntax for this.
As an example, lets say I have the following nested one-to-many relationships:
Artist->Album->Song
I first create an Artist
Artist artist = new Artist(parameters)
artist.save()
With the newly saved Artist I wish to then save a series of Albums and their associated Songs.
I thought something like this would work but I am getting mixed results.
Album album = new Album()
artist.addToAlbum(album)
Song song = new Song()
album.addToSong(song)
What I see is a new Album domain object, but no new Song. I tried a simple println to check the status of the "album" and it returns a null. So clearly I can add an Album to the existing Artist, but I am not getting back the Album itself so that I can add Songs. Can someone shed some light on how to save multiple nested objects in GORM/Grails?
Thank you
Actual Domains: Nested DataLoad->DataSeries->ReportedResult
DataLoad
class DataLoad {
static hasMany = [dataSeries: DataSeries]
String fileLocation
Date dateCreated
Date lastUpdated
CROSource croSource
List dataSeries = new ArrayList()
static mapping = {
dataSeries cascade:"all-delete-orphan"
}}
DataSeries
class DataSeries {
//parent and child relationships one-to-many
static belongsTo = [dataLoad: DataLoad]
static hasMany = [reportedResult: ReportedResult]
//this functions as an experiment_id for data which needs to be viewed together
String randomString
Date dateCreated
Date lastUpdated
List reportedResult = new ArrayList()
static mapping = {
reportedResult cascade:"all-delete-orphan"
}}
ReportedResult
class ReportedResult implements Serializable {
//parent and child relationships one-to-many
static belongsTo = [dataSeries: DataSeries]
static hasMany = [resultDefData: ResultDefData]
List resultDefData = new ArrayList()
//has one-to-one relationship -may need to make this a one sided relationship does not always need a Curve
Curve curve
AssayGroup assayGroup
AssayDefinition assayDefinition
AssayProtocol assayProtocol
ResultStatistic resultStatistic
ResultType resultType
//actual result fields
Float resultValue
String resultValueUnit
String resultModifier
Boolean resultObtained
Date resultTime
Integer compoundID
Float resultStatValue
String resultComment
Float resultRawValue
String linkToExternalFile
String studyNumber
Date dateCreated
Date lastUpdated
static mapping = {
resultDefData cascade:"all-delete-orphan"
}}
UPDATE
So if I try something like the following, it works. Must be something else in one of my domains. I will try to fix my issue, but for reference this should work.
Artist artist = new Artist(artistName: "MyName")
artist.save()
Album album = new Album(albumName: "myAlbum")
artist.addToAlbums(album)
Song song = new Song(songName: "just a song")
album.addToSongs(song)

Related

Realm query Object property field by its property

I'm developing an application for iOS using Swift and chose Realm as a database solution for it. I asked one question about Realm and now I have another.
Suppose we have a schema like this:
class Person: Object {
dynamic var id: String = NSUUID().UUIDString
dynamic var name: String?
dynamic var cars: Car?
class Car: Object {
dynamic var name: String?
I have one class (Person) that contains any number of objects of another class (Car). Car that are "linked" with the Person has some properties in context of that Person (and they can be different for same Car for different Persons or for two similar Cars for one Person). Using List<...>() we can not store such properties for each Item, am I right?
If we use Car only for one Person and only once we can create another class that includes only additional properties for Cars and links them with ID of Person plus ID of Car. But it does't work if we have two similar Cars with different additional properties.
So, how I see the solution. Have one table (class) stores ID of Person, ID of one Car and additional properties for this Car. For another Car for the same Person it has the same Person ID, Car ID (same or not) and another additional properties for this instance of a Car.
There is a problem (and a question that I mean). Having that structure I want to query all Cars from that table with their additional properties that have Person ID equals to some_id. How should I do this? Or maybe what another structure (maybe using List<...>) I should have to achieve such kind of behavior?
What is FastList exactly ?
If you want Items to have a property of Lists collection.
You have to redefine your Realm model. something like this.
class Car:Object{
dynamic var createDate: NSDate = NSDate()
}
class Person:Object{
let cars = List<Car>()
}
and query by predicate like this
let realm = Realm()
var ownedCarsFilterByDate = realm.objects(Person).filter("ANY cars.createDate = '\(date)'")
Edited to updated question
Your solution is to create table class, which has 'Person' , 'Car' and 'Context Attribute'.
Your model would be like this
class PersonAndCarRelation:Object{
dynamic var person: Person?
dynamic var car: Car?
dynamic var contextAttribute = ""
}
and you can query all cars associated with person
let personID = "123456789"
let personAndCarArray = realm.objects(PersonAndCarRelation).filter("person.id == \(personID)")
for personAndCar in personAndCarArray{
let personName = personAndCar.person.name
let carName = personAndCar.car.name
let context = personAndCar.contextAttribute
println("I am \(personName). I have a \(carName) with \(context)")
}

Grails/Gorm : Sorting hasMany relationship

I have a domain class that has a 'hasMany' relationship that I would like to sort on so results are consistent when retrieving. Below is an example of the domain class.
class Author {
static hasMany = [ books: Book ]
static mapping = {
books sort: 'title', order: 'asc'
}
}
This produces the following error.
Default sort for associations [Author->books] are not supported with
unidirectional one to many relationships.
How can I sort on title in this example?
I have been able to achieve sorting on another hasMany relationship. Any feedback would be most appreciated.
As the error suggests you need to make the relationship bidirectional for default order to work,
just add the following in Book domain
static belongsTo = [author:Author] if you need default sort order to work.
Check if it will work for you
class Author {
SortedSet books // add this to your Author domain
static hasMany = [books: Book]
}
class Book implements Comparable {
String title
int compareTo(obj) {
title.compareTo(obj.title)
}
}

Entity Framework not comparing same objects returned at different times

I want to be able to return a list of Vehicle objects that are free to be booked between specific dates.
I have a method that returns a list of the Bookings that are currently in the database between those days and each booking has a related vehicle object, so I know all the vehicles that are unavailable.
I have another method that returns a list of all Vehicles in the database but I need a way of comparing the Booking.Vehicle with the Vehicle objects returned from the list.
I tried this
foreach(var booking in bookings)
{
allVehicles.Remove(booking.Vehicle)
}
But the vehicle wouldn't remove, why are the objects not being compared correctly? Even though its the same vehicle object being removed.
//Testing to see if the objects compare as expected (they don't)
public static List<Vehicle> AvaliableVehiclesBetween(DateTime StartDate, DateTime EndDate)
{
List<Booking> bookings = Booking.BookingsBetween(StartDate, EndDate);
List<Vehicle> vehicles = AllVehicles();
Vehicle v = vehicles[0];
if(bookings[0].Vehicle.Equals(v)) {
vehicles = null;
}
return vehicles;
}
after I run this the vehicles doesn't equal null;
You could try using just the primary key ~ID for your matching
var bookedIDs = bookings.Select(b => b.Vehicle.ID).ToList();
var freeVehicles = allVehicles.Where(v => !bookedIDs.Contains(v.ID));
As for your actual question, you probably don't have a Comparator setup for your objects, so it's comparing by memory location/reference. What is the best way to compare two entity framework entities?
You can do two things.
1) If you need to compare the whole object, then you need to serialize both of the objects into any format(XML), and then compare it.Because objects contains some metadata, which may not be equals.
2) you can compare any of property of both objects like "VehicleId".
public static List<Vehicle> AvaliableVehiclesBetween(DateTime StartDate, DateTime EndDate)
{
List<Booking> bookings = Booking.BookingsBetween(StartDate, EndDate);
List<Vehicle> vehicles = AllVehicles();
Vehicle v = vehicles[0];
if(bookings[0]!=null && v!=null)
{
if(bookings[0].Vehicle.VehicleId.Equals(v.VehicleId))
{
vehicles = null;
}
}
return vehicles;
}

Grails Join Table column name

My Alert has many Location objects, and I have the join table alert_locations.
The generated columns are:
alerts_locations_id (I want this to be alert_id)
location_id
Here's my domain object:
class Alerts {
static hasMany = [locations:Locations,notifications:Notifications]
Date alertDateTime
String pest
String crop
static constraints = {
alertDateTime (blank:false)
pest (blank:false)
crop (blank:false)
}
}
static mapping = {
locations joinTable:[column:"location_id", key:"alert_id"]

Many-to-Many of members of the same domain class

In Grails, I like to have a many-to-many relation among entries of the same domain class Person. Relations will link to different persons the "leftPerson" and the "rightPerson" since the "Parent-child" and "Employer-Employee" relations will discriminate the position of each link.
That I would like to have is something like the following model:
class Person {
String name
static hasMany = [relations:Relation]
}
class Relation{
String type
Person leftPerson
Person rightPerson
static belongsTo = [person:Person]
}
Any entry in Relations will be visible from both Persons.
I like to avoid having in Person two entries in'hasMany'and mappedBy if possible.
Is there any way to do it?
Take a look on many-to-many example of GORM many-to-many chapter.
class Person {
String name
static hasMany = [relations:Relation]
}
class Relation {
String type
static hasMany = [persons: Person]
static belongsTo = Person
}

Resources