Declaring booleans in a domain class without appearing in database - grails

I have some booleans that are used throughout my grails project (services & controllers, etc) so they are declared in my domain class but I do not want them appearing in the table in the database. Instead of declearing them Boolean I tried Def but this isn't working. Is there a way to do this?

If you want to have a property of a domain class that does not get stored in the database then use transients.
Here is a simple example:
class Thing {
String name
boolean flag
boolean anotherFlag
static transients = ['flag', 'anotherFlag']
}

Something I picked up from one of the grails videos by Burt Beckwith was in grails domain classes if you define a getter or a setter without declaring the object itself that itself becomes a transient object by default. So as per above rather than all of the declarations if you had
//This will return the same value
boolean getFlag() {
return someField && someOtherField
}
//so you call `object.flag` or `object.getFlag()`
This saves from then having to declare a transient value as well giving you the chance to apply some logic on the fly.
In all honesty it appears you are using both the domain class for validation and input. Usually I separate and create a validation class in src to do this part and get domain class to do raw work - keeps it cleaner per say

Related

How can I stop my grails domain class from creating a table in my database

I need to make a model class which wouldn't require tables creation but I still want to be able to use tags associated with domain classes used in views and hence dont want to create those classes in src folder. Is there a way to do that without generating custom tags?
The mapWith static property adds the ability to control if a domain class is being persisted.
Example:
class Airport {
static mapWith = "none"
}
In above example the Airport class will not be persisted to the database.
Please check this for example and this for documentation.
Hope this will helps u.
Just put your domain inside src/main/groovy and tables will not be created.
Or in some situations you can use the 'embedded' declaration inside your domain object's nested object.

Grails dynamic "inList"

This is almost identical to this old question: Dynamic define the inList constraint using database query which was essentially unaddressed, perhaps there have been advances in the years since that was asked.
I'd like to populate the inList parameter of a domain attribute with values from another domain. Due to auto-generated views (scaffolding, filterpane), this needs to come from inList rather than a custom validator.
class MyDomain {
String someValue
static constraints = {
someValue(nullable: true, maxSize: 50, inList: SomeOtherDomain.list()*.name)
}
}
This gives the following error on startup:
Caused by: java.lang.IllegalStateException: Either class [thepackage.SomeOtherDomain] is not a domain class or GORM has not been initialized correctly or has already been shutdown. Ensure GORM is loaded and configured correctly before calling any methods on a GORM entity.
I know, the "correct" way to handle this is to make someValue an instance of SomeOtherDomain instead of just storing the name, but that doesn't quite fit. We want to be able to delete an instance of SomeOtherDomain without breaking the saved value of the owning domain... the domain with the deleted value will be invalid going forward, and would have to be updated before saving, but archived/locked records will still exist and can be displayed.
You can specify value lists for filterpane like this:
<filterpane:filterPane domain="MyObject" filterPropertyValues="${['someValue':[values: SomeOtherDomain.list().collect{it.name}]]}" />
And then just use a custom validator to actually validate. I'm not sure what scaffolding might use the inList but easy enough to get around that if you're OK with replacing a few scaffolded pages with static ones.

Grails 3 use springSecurityService in a trait? Serialization error-

To add a username "lastUpdatedBy" property (along with some other std properties) to several domain classes I created a trait. Everything works fine to the database, but EhCache disk storage gives a NotSerializableException on springSecurityService. I have
def springSecurityService
in order to get the principal.username.
Is there a way to designate the service as transient (static transients=[] doesn't seem to help), or am I at a dead end? Referencing a service from within a domain class is a bit dodgy anyway, but what is a better, workable way to get the username just before saving?
Ok, I figured this out. One of the domain classes had a composite key and was therefore tagged to implement Serializable. Once this was converted to maintain the usual id field and "implements Serializable" was removed, the problem went away.
Just declare your the field as a transient field.
class MyDomain {
// other stuff omitted
transient SpringSecurityService springSecurityService
}
This will do the job when it come to serialization.

Modifying return value of getters of String fields

Let's say I have classes similar to domain classes in my application with some Long, Double, Date and String fields. These classes extend base class with some common fields and few common methods. Whenever I access class field (though getter) that is String, I want to make some changes to the value returned (for example remove html tags). Is there a better way than making implementations of getters for each fields of String type? What about inherited fields?
Don't change default getter/setter implementations created for you by Grails. You would definitely mess up your application in various places. Grails uses convention over configuration so getters/setters should definitely remain unchanged.
Create your own methods that return what you want: for a field title create method getStrippedTitle(). You can add this method to transients too.
If you change the value that's set, or return a value that's different from what was set, you'll confuse Hibernate. That's because when you load an instance from the database, Hibernate keeps the original data in its 1st-level cache, and returns a domain object instance to you. When you flush, it compares the current state with the original, and if it changed, it will push the changes to the database. So if you return a different value than what was set, but don't really change the value, Hibernate can't tell the difference.
You're much better off leaving the properties alone and creating methods that return altered data. One convention I've used is that if for example you have a String body field, you can access it via the property name body or the getter getBody(), but you can create a body() method that's unknown to Hibernate and returns whatever you want.

Grails: derived fields in domain classes

Suppose I have a domain class branch which has several members:
…
static hasMany = [ members:Member ];
…
Now suppose I want to have the number of members of that branch readily available, to have it displayed in the list and view actions, so perhaps storing that information into a variable in the domain class itself would be a good idea?
…
Integer memberCount = members.size();
static constraints = {
memberCount(editable:false);
}
…
(Is this the correct syntax?) Edit: This is not the correct syntax. I cannot assess the size of the members list, as it doesn’t exist yet and grails will complain about size() not being applicable to null objects. What else could I try?
However, as memberCount is now a variable in the domain class, it is possible to assign a value to it upon creation of the Branch (which is contra-intuitive) and it will not be updated automatically once a new Member is added.
It is of course possible to reach the desired result in a different way. I could manipulate the view.gsp and list.gsp in the /Branch directory, add some additional <td>s there etc. But that does not seem very elegant to me.
Basically, I think what I am looking for is some way to tell grails that a certain variable is derived, should not be setable by the user, but update whenever necessary. Is there such way?
You can add any property you don't want persisted to the transients static list:
static transients = ['memberCount']
See this page in the manual
Also, this StackOverflow question answers the same question
Also, a better way to do derived properties may be to use the Derived Properties feature of GORM

Resources