Validation in domain class - grails

I have to validate whether this value of eventId already exist in mysql database.i have a database of event where the id are stored in event_id. so i need to validate this eventId already exists or not.
Domain Class:
class Event {
String eventId
static constraints = {
eventId(blank: false,nullable: false)
eventId validator: {val ->
if(val== event.event_id){
return false
}
}

You should use unique constraint provided by grails
e.g
static constraints = {
eventId unique: true
}

Related

Cannot redirect for object [ManageVehicle : (unsaved)] it is not a domain or has no identifier. Use an explicit redirect instead

This is my domain.
import org.apache.commons.lang.builder.EqualsBuilder
import org.apache.commons.lang.builder.HashCodeBuilder
class ManageVehicle implements Serializable {
String vehicle
Short truckKey=0
Short siteID
Integer unitID
String wheelConfig
String model
Short period=0
String usid=UUID.randomUUID().toString()
//static belongsTo = [wheelConfig : TTType,model:TTModel]
int hashCode() {
def builder = new HashCodeBuilder()
builder.append truckKey
builder.append siteID
builder.toHashCode()
}
boolean equals(other) {
if (other == null) return false
def builder = new EqualsBuilder()
builder.append truckKey, other.truckKey
builder.append siteID, other.siteID
builder.isEquals()
}
static mapping = {
table 'TF_Truck'
version false
truckKey column :'TruckKey'
siteID column :'SiteID'
id composite:['truckKey','siteID']
vehicle column: 'TruckID' ,sqlType: 'nvarchar'
wheelConfig column: 'TypID',sqlType: 'tinyint'
model column: 'ModID' ,sqlType: 'tinyint'
unitID column: 'McmID',sqlType: 'tinyint'
period column: 'Period'
usid generator: 'assigned', column:'USID', sqlType:'uniqueidentifier'
}
static constraints = {
period nullable: false
truckKey nullable: false
siteID nullable: false
}
}
And my save method in controller is .
def save(ManageVehicle manageVehicleInstance) {
manageVehicleInstance.siteID=RequestContextHolder.currentRequestAttributes().getAttribute("SiteID",RequestAttributes.SCOPE_SESSION) as Short
if (manageVehicleInstance == null) {
notFound()
return
}
if (manageVehicleInstance.hasErrors()) {
respond manageVehicleInstance.errors, view:'create'
return
}
manageVehicleInstance.save(flush:true,failOnError: true)
request.withFormat {
form {
flash.message = message(code: 'default.created.message', args: [message(code: 'manageVehicle.label', default: 'Manage Vehicle'), manageVehicleInstance.id])
redirect manageVehicleInstance
}
'*' { respond manageVehicleInstance, [status: CREATED] }
}
}
while i am applying save operation on this domain i am getting following exception .
Message: Cannot redirect for object [ManageVehicle : (unsaved)] it is not a domain or has no identifier. Use an explicit redirect instead
Suggest me some solution.
I guess that Grails cannot handle composite id in redirection.
I have two options in my mind to fix that case
Create id field for your domain class by removing id line from mappings
Implement custom redirection for your saved object like
redirect(action:'show', params:[truckKey:manageVehicleInstance.truckKey,siteID:manageVehicleInstance.siteID])
With 2. option you may also have to implement custom object loading into 'show' action using composite id like def manageVehicleInstance = ManageVehicle.findByTruckKeyAndSiteID(params.truckKey, params.siteID).

Grails: Legacy DB - Record with composite Id won't update

I'm having problems trying to update a record on a Grails 2.3.7 Project
I don't want to modify the fields that are part of the composite Id, I just want to update the other fields.
Just one class, few properties, but every time I try to update, it throws me the "not unique error" when this lines runs:
personInstance.validate()
if (personInstance.hasErrors()) {
respond personInstance.errors, view:'create'
return
}
My class looks like this:
class Person implements Serializable {
static constraints = {
name(unique: lastName)
}
static mapping = {
id generator: 'assigned'
id composite: ["name", "lastName"]
}
//Override equals and hashcode methods
boolean equals(other) {
if (!(other instanceof Person)) {
return false
}
other.name == name && other.lastName == lastName
}
int hashCode() {
def builder = new HashCodeBuilder()
builder.append name
builder.append lastName
builder.toHashCode()
}
String name
String lastName
String description
}
And the controller action:
def update() {
def personInstance = Person.get(new Person(name:params.name, lastName:params.lastName))
personInstance.properties = params
personInstance.validate()
if (personInstance.hasErrors()) {
respond personInstance.errors, view:'create'
return
}
personInstance.save flush:true
request.withFormat {/*etc...*/}
}
When I use validate(), it throws me a Grails unique key error, when I avoid validation its a BD not unique PK error.
Is like Grails didn't know if I want to do an insert or an update when I personInstance.validate().
Is there a way to manage this in a correct way that I'm not seeing?
Or am I forced to avoid validation?
am I doing something wrong?
Thanks in advance.
I believe the GORM mapping DSL expects just one id definition. Try combining your two id lines into just this one:
id generator: 'assigned', composite: ["name", "lastName"]
Also, in addition to implementing Serializable, your domain class should override equals and hashCode, as described under "Composite Primary Keys" here: http://grails.org/doc/latest/guide/single.html#identity

Grails 2.1 Join Query

I m new user in Grails. I don't know how to write projection query. Here is my code. please anyone help me for grails projection query.
From Join table I want to find username which is consist in user table
Given the following example domains:
class User{
transient springSecurityService
String username
String password
boolean enabled
boolean accountExpired
boolean accountLocked
boolean passwordExpired
static mapping = {
table 't04t001'
id column: 'f_account_id'
username column: 'f_username', length: 10
password column: 'f_password', length: 100
enabled column: 'f_account_active'
accountExpired column: 'f_account_expired'
accountLocked column: 'f_account_locked'
passwordExpired column: 'f_password_expired'
version column: 'f_revision'
}
}
class Role{
String role
static mapping = {
table 't04t003'
id column : 'f_role_id'
role column : 'f_role'
version column : 'f_revision'
cache true
}
}
class UserRole implements Serializable {
User user
Role role
static mapping = {
table 't04j002'
id composite : ['role', 'user']
role column :'k_role_id'
user column :'k_user_id'
version false
}
}
I can't figure out how to build the criteria to find all the user. I tried the following:
def criteria = UserRole.createCriteria()
def list = criteria.list {
projections {
user{
ilike('username', 'omar')
}
}
}
In console mode i have seen this query with message
Hibernate:
select
this_.k_role_id as k1_3406_0_,
this_.k_user_id as k2_3406_0_
from
t04j002 this_
where
(
lower(user_alias1_.f_username) like ?
)
However, it says Unknown column 'user_alias1_.f_username' in 'where clause'.
But i cant figure out this(user_alias1_) alias
I am not exactly clear on what you want to retrieve from which table. So based on your criteria query, here is how to retrieve user from the UserRole table.
def criteria = UserRole.createCriteria()
def result = criteria.list {
projections {
property("user")
}
user {
eq("username", "omar") //strict match
}
}
return result;
What this does is it builds a list that has the user.username as omar. By default the result will be the UserRole object, but to get user object instead we used projections.
Update:
Your Domain class seems a bit out of grails conventions. Why not user something like this?
//User.groovy
class User {
String username
// ..
static constraints = {
username blank: false, nullable: false, maxSize: 10
}
}
//UserRole.groovy
// Since you are using composite keys, we have to implement serializable. But is there a need for composite key in your situtation?
class UserRole implements Serializable {
User user
// ..
}
In you service class
// UserRoleService.groovy
def getUser(String username) {
def criteria = UserRole.createCriteria()
def result = criteria.get {
projections {
property("user")
}
user {
ilike("username", username)
}
}
return result;
}
And to call the service method from controller,
// ExampleController.groovy
class ExampleController {
def userRoleService
def index() {}
def someThing(String username) {
def user = userRoleService.getUser(username)
println user?.username
// ..
}
}

Inconsistency in GORM session if addTo* vs pass as argument at initialization

I have Many-To-Many relationship between RentalUnit and Review(there may be review for guests staying in multiple rental units). There is cascading on Delete from RentalUnit to Review but none cascading from Review to RentalUnit
While working with tests, i found following inconsistency in GORM session
def review2 = new Review(rentalUnits: [rentalUnit], ...., isApproved: false).save(flush: true)
review2.addToRentalUnits(rentalUnit2)
The 'rentalUnit2' object will have association to the 'review2' whereas the 'rentalUnit' does not.
How do i ensure consistent session while pass RentalUnit object at initialization or via addTo*?
p.s. Here is complete code
class Review {
String submittedBy
String content
String dateReceived
boolean isApproved
final static DateFormat DATEFORMAT = DateFormat.getDateInstance(DateFormat.MEDIUM)
static belongsTo = RentalUnit
static hasMany = [rentalUnits: RentalUnit]
static mapping = {
rentalUnits cascade: "none"
}
static constraints = {
submittedBy blank: false, size: 3..50
content blank: false, size: 5..255
dateReceived blank: false, size: 11..12, validator: {
try{
Date date = DATEFORMAT.parse(it)
return DATEFORMAT.format(date) == it
}catch(ParseException exception){
return false
}
}
rentalUnits nullable: false
}
}
class RentalUnit {
String name
String nickname
Address address
static hasMany = [reviews:Review]
static mapping = {
reviews cascade: "all-delete-orphan"
}
static constraints = {
name blank: false, unique: true
nickname blank: false
}
}
Your answer is in your question - use addToRentalUnits. It does three things; it initializes the collection to a new empty one if it's null (this will be the case for new non-persistent instances, but not for persistent instances from the database which will always have a non-null (but possibly empty) collection), adds the instance to the collection, and sets the back-reference to the containing instance. Simply setting the collection data just does the first two things.

How to map Domain Object Properties to Columns

I have this domain class.
class Book {
String code
String description
static mapping = {
table 'Book'
version false
}
}
and I have table BookStore with columns COD and DSC.
I need map to this table.
How can I achieve this?
If I understand your question correct, the sections within Mapping in the documentation should help you
For your example, the following should work:
class Book {
String code
String description
static mapping = {
table 'BookStore'
version false
code column: 'COD'
description column: 'DSC'
}
}
Also, within DataSource.groovy, make dbCreate = "update" under the appropriate environment that you are using. Refer the documentation on DataSource for this.
Hope this helps.
class Book implements Serializable {
String code
String description
static mapping = {
table 'BookStore'
version false
id composite: ['code']
code column: 'COD'
description column: 'DSC'
}
boolean equals(other) {
if (!(other instanceof Book)) {
return false
}
other.code == code
}
int hashCode() {
def builder = new HashCodeBuilder()
builder.append code
builder.toHashCode()
}
}

Resources