Grails check for unique constraint - grails

I have a Domain class Supplier:-
class Supplier {
static embedded=['address']
static constraints = {
vendorName(blank:false,nullable:false,maxSize:50)
address(blank:false,nullable:false,unique:true)
contactPerson(blank:false,nullable:false,maxSize:50)
}
String vendorName
Address address
String contactPerson
}
and the Address class:-
class Address {
String street
String area
static constraints = {
street(blank:false,nullable:false)
area(blank:false,nullable:false)
}
}
My requirement is to check for the uniqueness of street in supplier. when a user enter street and area from Supplier view, i have to check that street should be unique for a vendor.
thnks

It will be like that if only street should be unique
class Address {
String street
String area
static constraints = {
street(blank:false,nullable:false)
area(blank:false,nullable:false)
}
static mapping = {
street(index: true, indexAttributes: [unique: true])
}
}

Since you only have one Address per Supplier street is already unique per Supplier. If you can't have more than 1 address you can't have duplicate streets.

Related

How to set unique constraint in a hasMany relationship

I have this class:
class Word {
String word
static hasMany = [group: WordGroup]
static belongsTo = [language: Language]
static constraints = {
word(unique: ['language'], maxSize:255)
}
}
Which is working fine, but I would need to associate the unique constraint to both language and group, so different groups can insert the same "word".
The groups are in an intermediate table (WordGroup) as this is a many to many relationship.
If I try to do
word(unique: ['language', 'group'], maxSize:255)
I get the error
Missing IN or OUT parameter in index:: 3
Is there a way to do this?
EDIT: I am adding the other classes referenced in the Word class if it helps
WordGroup
class WordGroup {
static belongsTo = [word: Word, group: Group]
static constraints = {}
}
Group
class Group {
String name
String url
static hasMany = [words: Word]
static constraints = {
name blank: false, unique: true
}
}
Language
class Language {
String name
String code
static constraints = {
name maxSize:255
code maxSize:255
}
}
Thanks.

find list using createcriteria nested object property

I have a domain like this
Employee {
Address address
String name
String title
}
and another domain
Address {
String country
String locality
String city
}
and now i want to find the all the employee with given city something like that i tried
def employees = Employee.where {
address {
city == params.city
}
}
but this is not working , how can i achieve this
You can write it like following
List<Employee> employees=Employee.createCriteria().list{
'address'{
eq('city',params.city)
}
}
Note: When the eq('city',city) (same parameter name) is used, it will not work.
The syntax for accessing properties of associations differs between criteria and where queries.
Where query
def employees = Employee.where {
address.city == params.city
}
See https://grails.github.io/grails-doc/latest/guide/GORM.html#whereQueries
Criteria query
def employees = Employee.withCriteria {
address {
eq('city', params.city)
}
}
See https://grails.github.io/grails-doc/latest/guide/GORM.html#criteria

Grails - unique constraint in sub-class

Lets say I have this two classes in my application:
class User
{
static belongsTo = [company: Company]
Address address
Phone phone
String name
Integer salary
Date birthDate
}
and
class Company {
Boolean active = false
static hasMany = [users: User]
}
Something really basic.
I would like to make a constraint in Company class on the users field. That I won't have in the same company two users with the same name address and phone.
I should be able to add another user with this three matching fields for a different company. And, name is a nullable field so I should be able to have a few records with the same address and phone for the same company id the name is null.
Could someone please help me to define such a constraint?
See if this is what you are looking for, but make sure your company is saved first.
Company.withTransaction {
def compnay= new Company (active:true)
company.save(flush:true)
def user = new User (...)
compnay.addToUsers(user)
}
/
class User
{
static belongsTo = [company: Company]
Address address
Phone phone
String name
Integer salary
Date birthDate
static constraints = {
name unique: ['company','address','phone']
}
}
/
class Company {
Boolean active = false
static hasMany = [users: User]
}

GORM how to ensure uniqueness of related objects property

I'm trying to get my head around GORM and relational mapping. The relationships are working fine but there is one problem. I can't seem too ensure that every MailAddress added to MailingList has a unique address. What would be the must efficient way to do this?
Note: There is no unique constraint on MailAddress.address. Identical addresses can exist in the same table.
class MailAddress {
String name
String email
static belongsTo = MailingList
static constraints = {
name blank:true
email email:true, blank:false
}
}
class MailingList {
String name
static hasMany = [addresses:MailAddress]
static mapping = {
addresses cascade: 'all-delete-orphan'
}
static constraints = {
name blank:false
}
}
As mentioned in the comments by #ibaralf the answer is a custom validator.
The MailingList class needed to validate if all addresses (MailAddress) have a unique e-mailaddress.
I added this constraint to the MailingList class and it worked.
static constraints = {
name blank:false
addresses(validator: {
if (!it) {
// validates to TRUE if the collection is empty
// prevents NULL exception
return true
}
// Grab a collection with all e-mailaddresses in the list
def addressCollection = it*.email
// Compare to a collection with only unique addresses
return addressCollection == addressCollection.unique()
})
}
More info can be found here http://grails.org/doc/2.2.0/ref/Constraints/validator.html
There is a unique constraint you can add:
static constraints = {
name blank:true
email email:true, blank:false, unique: true
}
=> put the unique constraint on the email variable (unique: true). This would prevent identical email addresses to be saved in the table.

grails / gorm supporting different parent entity in 1 - many associations

I have the following "top-level" (parent) domain entities:
Customer
Company
Contact
And the following child entity:
Address
There is one to many relationship between each of the top level domain entities:
Customer -> Address
Company -> Address
Contact -> Address
i.e. a customer, company or contact can have one or more addresses.
Unfortunately I do not know how to model this in grails / gorm. It seems I can only define one parent or belongsTo declaration in address i.e. I was not able to declare Address using:
Address {
Customer parent //??
Company parent //??
Contact parent //??
}
Can someone tell me if I am missing something or if it's possible to define this type of relationship in a supported way?
Thanks,
cowper
You should be able to use the array version of belongsTo as Tim pointed out:
Address {
static belongsTo = [Customer, Company, Contact]
}
If entities can share a common address may change the way you configure deletes.
Another option is to have those three classes inherit the property from a superclass, but whether or not that makes sense in your case, I don't know (it kind of doesn't look like it).
In our application we have several entities that need addresses. But we've chosen to model them in a many-to-many relationship.
Address looks like this
class Address {
// typical address properties
Set<Company> getCompanies() {
CompanyAddress.findAllByAddress(this).collect { it.company } as Set
}
static constraints = {
// typical constraints
}
}
And for each "parent" we provide a getter. You can see getCompanies() in the code above. If you're only every going to have 1 company per address, then simply have that getter return the 1 company instead of a Set. The inverse is true inside Company, we have a getAddresses().
Company Address, for example, looks like this...
class CompanyAddress implements Serializable{
Address address
Company company
boolean equals(other) {
if (this.is(other)){
return true
}
if (!(other instanceof CompanyAddress)) {
return false
}
other.address?.id == address?.id &&
other.company?.id == company?.id
}
int hashCode() {
def builder = new HashCodeBuilder()
if (address) builder.append(address.id)
if (company) builder.append(company.id)
builder.toHashCode()
}
static CompanyAddress get(long companyId, long addressId) {
find 'from CompanyAddress where address.id=:addressId and company.id=:companyId',
[addressId: addressId, companyId: companyId]
}
static CompanyAddress create(Company company, Address address, boolean flush = false) {
new CompanyAddress(address: address, company: company).save(flush: flush, insert: true)
}
static boolean remove(Company company, Address address, boolean flush = false) {
CompanyAddress instance = CompanyAddress.findByAddressAndCompany(address, company)
instance ? instance.delete(flush: flush) : false
}
static void removeAll(Address address) {
executeUpdate 'DELETE FROM CompanyAddress WHERE address=:address', [address: address]
}
static void removeAll(Company company) {
executeUpdate 'DELETE FROM CompanyAddress WHERE company=:company', [company: company]
}
static mapping = {
id composite: ['address', 'company']
version false
}
}

Resources