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.
Related
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.
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
how audit-logging can work in domain class like userRole from springSecurity?
class SecUserSecRole implements Serializable {
static auditable = true
User user
Role role
...
def onSave = { map ->
println "onSave userRole detected"
}
}
thanks anyway..
I am not fully understanding why this is not working, but the reason seems to be auditPlugin cannot get the persisted properties when the id for class is composite. Therefore, it assumes nothing has changed and it wont call onSave.
The generated SecUserSecRole class introduces a composite key for ID based on 'role', 'user' and auditPlugin is trying to find the persisted property names from the hibernate PostInsertEvent. At this its not clear know why but the properties will be empty when domain is using composite key.
As a workaround try to change your domain mapping to
static mapping = {
//id composite: ['role', 'user']
role unique: 'user'
version false
}
NOTE: This is not a solution and might have other side effects as far as springSecurity plugin.
Update: My concern was removing composite key might impact springSecurity many-to-many relationship, but according to Burt's post, seems it is safe to remove composite key and just create it unique as I mentioned here.
I am trying to map a legacy domain class to my grails class, but when table is generated, the field associated with legacy class is Tinyblob, and not a BigInt linked with ID, and foreing key stuff.
class NewClass implements Serializable {
GrailsEntityA grailsEntityA
GrailsEntityB grailsEntityB
LegacyEntity legacyEntity
}
The table has foreing keys for GrailsEntityA and GrailsEntityA but not for LegacyEntity, the type is tinyblob, without relationship with the LegacyEntity table.
Is it possible do this? How?
I have a domain class having an Integer variable 'code'. my requirement is to make 'code', primary key column for that domain and also auto increment and to remove the default 'id' column from the table created for that doamin.thnks
use this :
static mapping = {
id name: 'code'
}
more informations here :
http://grails.org/doc/2.0.x/ref/Database%20Mapping/id.html
Domain classes in Grails by default dictate the way they are mapped to the database using sensible defaults. You can customize these with the ORM Mapping DSL.
Customizes the way the identifier for a domain class is generated with id.
See the Grails documentation for id.
static mapping = {
id column: 'code', type: 'integer'
}