use grails unique constraint only for generating DDL - grails

I would like to generate multicolumn unique constraints in Grails such as one defined in following entity class
class Relationship {
Element source
Element destination
Type type
// other properties omitted
static constraints = {
type unique: ['source', 'destination']
}
}
but I don't want to have that constraint active during the validation as it consumes lot of resources (see alternative to grails multicolumn unique constraint (optimistic inserts)) for stats.
Is there any way to achieve that? What are the alternatives to generate the unique index automatically (with checking for existing one)?

I've done this in an app where I knew that a column's values were unique based on how they were generated, so I didn't want Grails to run a select query during validation, but wanted the database check just in case something weird happened.
I would do this using a database migration. Add whatever constraints and indexes you like, in addition to the updates that are needed to keep the code and database in sync (e.g. adding/removing columns or tables, changing column types, etc.)

Related

Does a hasMany relationship in GORM require an indexColumn?

I'm dealing with legacy tables right now. Our Grails app will simply display data. All data entry and updates take place using a different tool. It would be very difficult to add columns to the legacy database. Are indexColumns absolutely, positively required? Or is there some way I can simply not use indexColumns at all in this case?
http://grails.org/doc/latest/ref/Database%20Mapping/indexColumn.html
Not if it is a Set, which is the default type for hasMany relationships.
By default when mapping an indexed collection such as a Map or List the index is stored in a column called association_name_idx
Grails documentation

Grails domain class Constraints vs Legacy DB constraints

I am using grails GORM for database mapping and oracle as database which is already populated with values.My question is can I define a new constraint like Foreign key in the domain class even if its not defined in the underlying table in my legacy db?The grails app is still going to accept the constraints right?The constraints dont have to exactly match those of database right?
you can define attributes of a class, which are not saved in the db and due to this don't need a representation in the db these attributes are defined as follows:
class Person {
String name
static transients = ['name']
}
see information about transients. In 2.x transients are not auto-bound as listed in the docs here, so you have to do a bindable: true explicitly.
Yes, the constraints you define in your domain class will be respected regardless of what you have in your database. The only time the 2 really relate is if you are letting Hibernate generate DDL for you (which most folks do not do for their production environment) in which case there are certain constraints which affect the DDL that is generated. Since you already have a database you almost certainly have that turned off.
EDIT:
An example of a constraint which affects DDL is the size constraint. If you constrain a String field with something like size: 5..15, by default the DDL that is generated will create a column that is 15 characters wide. If you are not allowing the app to generate DDL that constraint is still applied at validation time and if the property has more than 15 characters or fewer than 5, validation will fail. Once validation passes and the data is sent to the database, the framework assumes everything will be ok there. If it isn't, then corresponding exceptions may be thrown. For example, if the String has 12 characters it will pass validation in the app and will be sent to the database. If the database column is only 8 characters wide, you are going to get a SQLException. I hope that makes sense.

Can grails domain class include custom criteria in every query?

I'm creating a domain class that will connect to an existing database. Unfortunately multiple domain objects are stored in the same table (the table is very generic), and I'm trying to find a way to include additional criteria in each query that is made through GORM.
For example, I have an Article domain class which exists in the exp_channel_data table. The table has site_id and channel_id columns, which will be used to indicate if the row is actually an Article (where site_id=2, and channel_id=3).
I can setup custom constraints to make sure that validation works properly:
static constraints = {
site_id validator: { it == 2}
channel_id validator: { it == 3}
}
But I want to prevent invalid Articles from even being returned in the first place (keeping things clean, and also for performance reasons).
What I'm envisioning is the ability to override every query that goes out from my domain class, and insert where site_id=2 and channel_id=3 so that I don't even see invalid rows.
Any thoughts would be appreciated, thanks in advance.
UPDATE
After using the hibernate-filter plugin (suggested below), this is what I'm using in the domain class to prevent unnecessary entries from being returned.
static hibernateFilters = {
site_idFilter condition: 'site_id=2', default: true
channel_idFilter condition: 'channel_id=3', default: true
}
From what you are describing here, since it's per domain class, this looks to be a perfect situation for using the Hibernate filters plugin for Grails. This way you can define default constraints to be applied to criteria from those domains. Well worth a look to see if it will meet your needs.

How to create model from database preserving 'default' constraint values

My existing table contains nearly 50 columns, most of them have the 'default' constraint.
I have created the model based on this database table. All seemed ok, until i tried to insert a new row. I've got a sql server error stating that some column cannot be null. It appears that creating a model from the database did not preserve the default constraints.
I edited the model manually adding all the defaults and after that inserting didn't fail.
So my question is, how do i create a model that automatically picks up default constraints associated to the columns?
Using mvc4, visual studio 2010, sql server 2008 r2.
Google search didnt make sense as all the people seemed to be talking about something different than what i need.
Pretty sure my answer from Possible to default DateTime field to GETDATE() with Entity Framework Migrations? will work for you too. By using a modified MigrationCodeGenerator class and iterating through the operations list you can update the columns and add DefaultValueSql values based on whatever rules you need.
Well, you have a number of options. You could set the default values in the Model's default constructor. I think this is the better solution.
If you must have the default constraints in your database you could do set defaultValueSql in your data migrations like this:
AddColumn("ExistingTable", "NewColumn",c => c.Int(nullable: false, defaultValueSql: "0"));

Entity Framework - Creating a lookup NavigationProperty

Quick question that requires a long explanation..
Say I have two tables - one is an item table (say 'Users') and another is a definition table - like 'Custom Properties'. Many different items in the system ('Users', 'Articles', 'Posts', etc) can all have custom property defined to them, and these are stored in the 'Custom Properties' table. So, for example, the 'Custom Properties' table looks like:
CREATE TABLE [CUSTOMPROP_DEFINITION] (
[ITEM_TYPE] INTEGER NOT NULL,
[POSITION] INTEGER NOT NULL,
[NAME] NVARCHAR(MAX) NOT NULL
)
Simple little table. Each item has a 'item_type' id (for example, a user is an item type of 1. Article would be an item type of 2, and so on), so this table could have multiple rows for each item. Essentially, this table's metadata for the other tables.
I want to create a navigation property on my Users table, that will link to all the entries in the props table where 'item_type' == 1.
What's the best way of going about this? From the way I see it, there are two options -
(1) Creating a navigation property through the EDMX and letting it populate it automagically. (This is preferred, but having troubles implementing..) or
(2) Creating a property in the partial class, and having that load everything manually.
The issue with #2 is that it would (could potentially?) be slower than having the entity framework handle loading.
The issue with #1 is that.. no matter what I try, I can't get a NavigationProperty defined that will handle it. Because the primary key is a fixed number - i.e. It will always be '1' for ALL Users, always be '2' for all articles, etc.. - I haven't been able to find a way to hook into that.
Thoughts?
--Mike.
What you're describing isn't really a "Navigation Property" in terms of what EF defines as a naviation property. A navigation property in EF terms follows a [usually] primary key - foreign key reference in the database schema itself. And, AFAIK, the only way to get that navigation property in the EDMX is for there to actually be a FK involved.
You could, obviously (and probably do) have a FK here, but that's not entirely what you want, because that FK is going to return all instances of your custom properties for the given primary key. What you want is instances of only a particular type; and I don't think there is a "off the shelf" way of doing this in EF.
What you probably want to do is implement a Stored Procedure, and bring that into your model; you could then implement this is a property (or probably more appropriately a method) on your entity.
Alternatively, you could just create the FK, have your entity load all of the custom properties, and then write "helper properties" that do simple LINQ based .Where() filters.

Resources