0

I found a very strange behavior in our grails application today that i want to share with you.

We are using grails 2.3.11 on mysql 5.1.48.

We had a DomainObject.findById( id ) in one of your Controller actions. We failed to check the id for a null value so DomainObject.findById( null ) would be called when no id is passed as an argument.

Normally DomainObject.findById( null ) will return null but there is a special condition that will yield other results!

If the controller action called before that inserted a new record in the database (lets call it Object B), regardless of the domain object stored, the DomainObject.findById( null ) will find the DomainObject with the same Id the Object B got on insert.

So when the controller action called before saved anything the findById(null) will return a row. And that row will have the same id the last inserted element got.

I am totally aware that using findById(null) is not the desired way to do it but I was quite shocked about the results it yielded. But returning any seemingly "random" result seems very strange to me.

I also want to note that DomainObject.get(null) will not suffer from this problem.

Anybody else witnessed this?

There is an active Jira pointing in this direction: https://jira.grails.org/browse/GRAILS-9628 but its not really describing this issue.

Colonel Thirty Two
  • 23,953
  • 8
  • 45
  • 85
Oliver
  • 117
  • 1
  • 5

2 Answers2

0

We don't really support passing null as an argument to a dynamic finder like that. Dynamic finders have explicit support for querying by null. Instead of DomainClass.findByName(null) you would call DomainClass.findByNameIsNull(). If you have a reference that may or may not be null, instead of passing that as an argument to a dynamic finder, the code can almost always be made cleaner by writing a criteria query or a "where" query that has a conditional in it.

I hope that helps.

Jeff Scott Brown
  • 26,804
  • 2
  • 30
  • 47
  • When I saw this question and tested in one of my apps, the query was 'correctly' sent to the database as `id is null` - I agree it is better to be explicit and test for null in code, but why does GORM sometimes handle this and other times not? Does it depend on the specific database driver? Hibernate/GORM version? – Gregor Petrin Nov 18 '14 at 08:05
  • ty for the observation. I am aware that its partly my fault, i was just puzzled about the results. I guess that it should not be too hard to handle findByXXX( null ) as findByXXXIsNull because thats what people are expecting to happen. I had no time yet to test it with different databases but i can confirm that the same error is not happening when we deploy our application to a server using maria-db. Maybe its related to the development environment. – Oliver Nov 18 '14 at 08:31
  • @Oliver Do you have a question or is "Anybody else witnessed this?" really it? – Jeff Scott Brown Nov 18 '14 at 13:33
  • You are somehow right, the main reason i created this page is to share my concerns. I am wondering if it should be advised to use dynamic finders at all considering their limitations regarding null values. – Oliver Nov 19 '14 at 07:28
  • @Oliver "...i created this page is to share my concerns." - https://groups.google.com/forum/#!forum/grails-dev-discuss is a better forum for sharing concerns. StackOverflow is really for asking questions. The answer to "I am wondering if it should be advised to use dynamic finders at all..." is of course "yes". For certain queries they are simple to read, simple to write and very expressive. Use them where they make things better and where they don't, don't use them. – Jeff Scott Brown Nov 19 '14 at 13:11
  • If you have to do null checks before every dynamic finder call, that would be tedious and not ideal at all. However, there are lots of scenarios where you will have a reference that you already know can't possibly be null and would like to use that value as query criteria. If the query is a simple one, dynamic finders might be perfect there. – Jeff Scott Brown Nov 19 '14 at 13:15
  • The thing to do is understand how the different query options work (dynamic finders, "where" queries, criteria queries...) and if you understand each of their strengths and limitations, you will know when each of them makes the most sense. None of them are perfect for every scenario. If any of them were, there would be no need to have more than 1 option. Use the one that makes sense for a particular scenario. – Jeff Scott Brown Nov 19 '14 at 13:18
  • "where" queries really are probably the most powerful. When written well they can be very easy to read. They have a little more syntax than dynamic finders but are still very expressive. They are type checked at compile time. They have all of the `DetachedCriteria` benefits associated with them. I think they were a great innovation for GORM. – Jeff Scott Brown Nov 19 '14 at 14:03
0

Thx for your information scot.

I have further details. This behaviour is also altered by the underlying database. While mysql suffers from this, maria-db (a mysql clone) does not!

So what happens is bound to the underlying database system. That should not happen to an abstraction layer ....

Oliver
  • 117
  • 1
  • 5