GORM: embed a class containing a reference to a domain class - grails

Given:
User, File are domain classes
src/groovy/Container.groovy:
class Container {
User user
File file
Date dateCreated
}
grails-app/domain/WithContainer.groovy:
class WithContainer {
Container c
String text
static embedded = ['c']
}
I was aiming at mapping WithContainer to a table with the columns:
user_id | file_id | date_created | text
Is that achievable with GORM?
This setup yields:
org.hibernate.MappingException: Could not determine type for: User, at table: with_container, for columns: [org.hibernate.mapping.Column(c_user)]
Thanks

Container is not a domain class because it isn't defined under grails-app/domain/.
It may be that you are confused about the embedded attribute. Properties in the embedded list are persistent properties for which you want all of their attributes stored in the same table as the owning class (WithContainer in your case), as opposed to being stored in their own table and referenced with foreign keys. The property still needs be an instance of a domain class though.

Related

GORM creating tables with base class name instead concrete class name

I Have the following domains in my gorm package:
Domain.groovy
package gorm
class Domain {
String createdBy
static constraints = {
}
static mapping = {
tablePerHierarchy true
}
}
User.groovy
package gorm
class User extends Domain {
String name
static constraints = {
}
}
I want a table named user with the fields of the base class domain, but instead GROM generate a table whit this specification
create table domain
(
id bigint auto_increment
primary key,
version bigint not null,
created_by varchar(255) not null,
class varchar(255) not null,
name varchar(255) null
)
I'm using mysql driver with grails 2.5.6.
It generates the table with the name as domain because you are using tablePerHierarchy true in your mapping.
Basically, you will get one table where you can set different discriminators for the subclasses.
See here for more information on inheritance strategies: http://docs.grails.org/2.5.x/guide/single.html#GORM
(scroll down to: 7.2.3 Inheritance in GORM)
If you simply want schema-export to generate your table with the name as user, then you would need to add the following to your mapping block in the Domain class:
table 'user'
so the entire mapping block would look like:
static mapping = {
table 'user'
tablePerHierarchy true
}
However, this may not make sense to name the table user if you have other classes extend from Domain.
(and if you don't plan to have other classes extend from Domain, then just add your fields into your User domain).
If you want to generate two tables (Domain and User), then set tablePerHierachy false.
Here is a great write-up with examples that may help you decide which way you want to go for your project:
https://sysgears.com/articles/advanced-gorm-features-inheritance-embedded-data-maps-and-lists-storing/
As a side note: I'm not keen on the name Domain for a domain class; it is too generic and may get confusing when you are talking about the specific Domain class vs domain classes. At least name it BaseDomain.

Grails Domain Class Inheritance: Configure Class Column

I use inheritance in Domain Classes in my Grails app. Obviously, inheritance adds a "class" column to my database. The content of the "class" column is the fully qualified name of the Domain Class, e.g. com.myapp.MyClass.
Now if I ever so some refactoring and the class name is no longer com.myapp.MyClass but e.g. com.myapp.mypackage.MyClass, then the database still contains the old class name which now no longer exists in the app.
Is there any way to configure the string that is put in the "class" column? Like another unique identifier for the class which is then mapped to the class name in my Grails config or something like this?
I think what you need is discriminator for the class.
By default when mapping inheritance Grails uses a single-table model
where all classes share the same table. A discriminator column is used
to determine the type for each row, by default the full class name. ref
You can map it like this:
class PodCast extends Content {
…
static mapping = {
discriminator "audio"
}
}
Look this documentation it gives you more options to customize it in more details
http://grails.org/doc/latest/ref/Database%20Mapping/discriminator.html

Retrieve collection in domain class from Database

We use dynamic scaffolding in our project and hence place maximum coding in Domain itself.
I have a requirement where I want to retrieve a collection for a Domain class property from the same domain class.
Example :
class Person{
String name
String school
}
school property should be a dropdown containing list of all schools so far available in the Person table. If no value available, it can be empty dropdown.
Any suggestions to achieve this in domain class itself?
That is what
static hasMany is for: http://grails.org/doc/latest/ref/Domain%20Classes/hasMany.html
in your case, something like below will work , once you create a School Domain object:
class Person{
...
static hasMany = [schools: School]
...

Code First mapping

I'm trying to map a Department to an Employee.
This is the Department Class:
Class Department
Property DepartID As Integer = 0
Property DepartName As String
End Class
If I define the Employee Class as follows:
Class Employee
Property EmployeeID As Integer
Property DepartID As Integer
' Navigational Property
Overridable Property Depart As Department
End Class
As you can see, the structure is very simple. Basically the Employee Table stores a Department ID, and I would like to automatically populate the Department Property.
I am easily able to map the Foreign Key using Fluent API if I have the Foreign ID field defined in Employee:
.HasRequired(Function(e) e.Depart).WithMany.HasForeignKey(Function(e) e.DepartID).WillCascadeOnDelete(False)
However, I would like to acheive the same without defining an ID property (DepartID) in the Employee Table. It's just going to be a bit cleaner, as I don't have to have multiple ID fields. Is it possible?
I suppose you mean DepartID in Employee class (not table, see my comment). If so, you can use ForeignKeyNavigationPropertyConfiguration.Map method to map it without the FK in model.

Grails - Multiple Tables in Single Domain Class

I have two tables with a common primary key. Now i want to get data from that both tables and show in single view using that primary key.
How i can get both table data in single domain class? How can i specify mapping?
For Example
Table-A and Table-B both are in single schema ABC
class X {
int id
String name
static mapping = {
table name: "Table-A", schema: "ABC"
columns {
name column:'name'
}
}
}
now i want to get address from table-B so that my view looks like below
ID NAME ADDRESS
2 HSJHD 23 X-Street Washington USA
How to get two table data in single domain class?
This sounds like a foreign key relation, you would simply use belongsTo in each object (provided a one-to-one relationship).
http://grails.org/doc/latest/ref/Domain%20Classes/belongsTo.html
Otherwise you could create a database view on your database, then create a domain object to match that view. Creating a domain based on a database view is identical to creating a domain based on a table.
Few options
Just use hql to query and join on the primary key
Create a view from the two tables, and map new table to that view
Use belongs to and when u access one object then access the other
You will need to use constraints: http://www.grails.org/doc/2.0.x/ref/Constraints/Usage.html
and http://www.grails.org/doc/2.0.x/guide/single.html#constraints

Resources