Grails Domain Class with Inheritance fails to set errors after validate - validation

I am experiencing a very strange behaviour in some of our domain classes after upgrading vom grails 2.1.4 to 2.3.11.
The Domain Objects i am talking about use inheritance and also has embedded properties.
Here is a simple outline of the structure we are using
abstract class A {
String normalProperty
ComplexType embeddedProperty
static embedded = [ 'embeddedProperty' ]
}
class B extends A {
String someMoreProperties
static hasMany = [ cs: C ]
}
class C extends A {
String evenMoreProperties
static belongsTo = [ b: B ]
}
I can save a instance of B without errors.
When i try to create a C object and add it to the list in B and save B i will get the following error:
Caused by: java.lang.NullPointerException
at org.codehaus.groovy.grails.orm.hibernate.metaclass.AbstractDynamicPersistentMethod.setupErrorsProperty(AbstractDynamicPersistentMethod.java:100)
at org.codehaus.groovy.grails.orm.hibernate.metaclass.AbstractSavePersistentMethod.doInvokeInternal(AbstractSavePersistentMethod.java:156)
at org.codehaus.groovy.grails.orm.hibernate.metaclass.AbstractDynamicPersistentMethod.invoke(AbstractDynamicPersistentMethod.java:63)
at org.codehaus.groovy.grails.orm.hibernate.HibernateGormInstanceApi.save(HibernateGormInstanceApi.groovy:196)
I investigated the issue and found out that validation is no longer working.
If I call b.validate() or c.validate() b.errors and c.errors will still be null.
This is causing the null pointer exception on save.
The odd thing is that there will be an errors Object when there is an actual validation error in the object, its only null when validation is passed.
Usually when you validate an entity the errors field will have the value of a grails.validation.ValidationError Object. However for my B and C objects the error field will be either null if there was no error or org.springframework.validation.BeanPropertyBindingResult if there was an validation error.
Any help or pointers are greatly appreciated .

Related

Kotlin Spring Request Blank Validation Best Practice

I'm new to kotlin and so far I have 2 options to do not blank validation on incoming HTTP request since a blank string considered as valid value in kotlin null checking.
Validation on class init function
data class Foo(val key: String) {
init {if (this.key.isEmpty()) throw Exception("Invalid Request")}
}
Validation with javax annotation
data class Foo(#field.NotBlank val key: String)
Both ways are working as expected, I just curious on what's the best way to do this in kotlin. I'm afraid that my kotlin code is to java, at that point no use I work with kotlin
If you want to validate the incoming request, go for 2nd option.
Consider having more than one attribute, lets say you have class such as:
data class User(val name: String, val surname:String)
Then you have to write validation for each field. What if both name and surname are blank? The name validation throws an error, you add name to request and BAM, surname validation throws an error.
data class User(val name: String, val surname:String) {
init {
if (this.name.isEmpty()) throw Exception("Name is missing")
if (this.surname.isEmpty()) throw Exception("Surname is missing)
}
}
You can validate all at once, using OR for example, but then you would lose explicit error - what was wrong? Blank name? Blank surname? Both were blank...?
data class User(val name: String, val surname:String) {
init {
if (this.name.isEmpty() || this.surname.isEmpty()) throw Exception("Name or surname is missing")
}
}
Now think about three, four, five fields.
If you use javax.validation properly, you have to write just the annotations and the rest is done by the framework - it will explictly say, what is wrong, on which field, because it checks all the constraints and if there are any violations, it throws an error with all violation details.

The given id must not be null with Spring Data

I'm developing an application written in Spring Framework 5, I'm also using Spring Data to access the PostgreSQL database, and I have a strange problem which occurs sometimes when I'm querying the database.
In short, I have a service which contains myMainFunction. That function is called from the controller, and that function calls myFunction which calculates and sets the ID to the object. myFunction then also queries the database to find if the object with calculated ID already exists in the database.
Then myMainFunction again quires the database to get the object with the same ID, if it exists. This is the line where java.lang.IllegalArgumentException: The given id must not be null! is sometimes thrown.
I can't understand why is this happening, and why is that happening sometimes, not all the time?
This is the "pseudo-code" which causes the problem:
publi class MyService {
...
public myMainFunction(MyObject object) {
...
myFunction(object);
Optional<MyObject> oldObject = objectRepository.findById(object.getId());
...
}
private void myFunction(MyObject object) {
...
object.setId(calculateId(...));
Optional<MyObject> existingObject = objectRepository.findById(object.getId());
...
}
...
}

grails 3 ConstraintException

I'm using grails 3.02 and all was fine, but since I moved several domain classes from another grails project I started seeing this error when I do start integration tests:
grails.validation.exceptions.ConstraintException: Exception thrown applying constraint [unique] to class [class com.mypackage.Individual] for value [true]: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext#6397593b has not been refreshed yet
The domain class code:
class Individual {
String institutionId
String email
static mapping = {
table 'db.individual'
id generator: 'sequence', params: [sequence: 'db.individual_id_sequence']
institutionId index: 'db.individual_institution_id_idx'
email index: 'db.individual_email_idx'
}
static constraints = {
institutionId(blank: false)
email(unique: true)
}
}
The strange thing is: this code is working in another project but does not want to work in this one, in where I moved it to. I compared configs(application.yml and application.groovy and build.gradle) - but all is basically the same.
Any help, grails gurus?
I think I have found why I had this exception. It was not related to constrains at all.
I just had some other fields in my domain class which used to be calculated, so it was unmapped field. But grails used to try to map this field into a real database column. Once I've defined my own getter(in which the field initializes) for this calculated field all became fine.
But the grails exception btw is stupid and disorienting - it does not describe the root cause at all.

MVC ExecuteQuery not a valid method on Context object

I am trying to execute a sql command directly against the database. However, intellisense does not see ExecuteQuery as a valid method against my context variable. I am sure I am missing something obvious.
My context class:
public class CatastropheContext : DbContext
{
public DbSet<CLIENT> CLIENTs { get; set; }
...
}
My attempt to establish the query:
CatastropheContext db = new CatastropheContext();
IEnumerable<ClientClaim> = db.ExecuteQuery
In the code above, ExecuteQuery is flagged as invalid an intellisense suggests creating a stub method.
Can you use Database.ExecuteSqlCommand where Database comes from the DbContext class.
This seems to me like you are missing some references. Make sure you are:
using System.Data.Linq;
Here is the MSDN reference on ExecuteQuery. Notice the namespace.

Groovy validation problem

I have a groovy system configured using tomcat and Oracle 10g.
I have a groovy class which defines an follows: (reduced version)
class ChangeTicket {
static constraints = {
chngNr(nullable:false)
}
String chngNr
}
My controller has defined a save method:
if (changeTicketInstance.validate() && !changeTicketInstance.hasErrors() && changeTicketInstance.save()) {
flash.message = "changeTicket.created"
...
}
As far as I know the save method calls by default the validate method in order to
know if the constraints are fullfilled or not therefore the validate method call is redundant. Anyway, when the save is performed an exception will be thrown if the field chngNr is NULL.
In fact the field cannot be empty (NULL) because I've defined the constraint (nullable:false).
What am I doing wrong here?
Thanks in advance,
Luis
The validate call should fail if chngNr is NULL. Some databases do not consider an empty string ("") null (HSQL). If you are binding chngNr to changeTicketInstance using params from a form it is getting assigned an empty string as a value and in that case you would want your constraint to be:
chngNr(blank:false)
Also, save() wont throw an Exception unless you use save(flush:true). Hibernate queues up the changes and, unless you flush, wont throw an actual exception.
try this:
chngName(blank:false,nullable:false)
:-)

Resources