Announcement Announcement Module
Collapse
No announcement yet.
Grails 1.3.3 Hibernate Oracle 11 problem Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Grails 1.3.3 Hibernate Oracle 11 problem

    Earlier this year I worked on a project using Grails 1.2.x and Oracle 10g, and things went very well. It's been a little while, but now I'm in a new environment, and having problems with getting very simple integration tests to persist objects, with some strange errors and other stranger errors. First, the problem:

    I have an (simplified) domain object representing an application in Application.groovy

    Code:
    class Application {
    
      String applicationName
      String applicationDescription
      String applicationStatus
    		
      static constraints = {
        applicationStatus(nullable:true, inList:["Plan", "Retire", "Build", 
          "Operate", "Decommissioned"])
      }
    	
      static mapping = {
    	table 'app_applications'
      }
    	
    }
    The mapping is needed because this is an existing table, and after this gets our of development I will set the cache: to readonly.

    In my integration test I have a method like the following:

    Code:
    void testSimpleSave() {
      def app = new Application( applicationDescription: 'desc', 
        applicationName: 'name', applicationStatus:"Plan" )
      assertNotNull app.save()
      assertNotNull app.id
      def foundApp = Application.get(app.id)
      assertEquals 'name', foundApp.applicationName
    }
    When I run this test with "grails test-app" I get the following:
    Code:
    Testcase: testSimpleSave took 0.61 sec
    	FAILED
    junit.framework.AssertionFailedError: null
    junit.framework.AssertionFailedError: junit.framework.AssertionFailedError: null
    	at com.jpmc.gti.gssd.brews.ApplicationIntegrationTests.testSimpleSave(ApplicationIntegrationTests.groovy:22)
    I take this error to mean that the object (app) to be persisted is null after the new().

    The table that the mapping points to exists, and if I scaffold a grails controller for this domain object, everything seems to work perfectly, including calling save() from the grails app.

    I'm using Grails 1.3.3 and Oracle 11, with the dialect = "org.hibernate.dialect.Oracle10gDialect".

    Any thoughts here? I would appreciate any insights.

    Brian

  • #2
    If save returns null, then validation failed. Try adding a "println app.errors" after the save but before an assert, e.g.

    def app = new Application( applicationDescription: 'desc', applicationName: 'name', applicationStatus:"Plan" )
    app.save()
    println app.errors
    assertFalse app.hasErrors

    You can view the app.errors output by going to the System.out link in the JUnit results.

    Comment


    • #3
      Grails persistence

      I would have thought the the object might have been invalid, but the constraints, they are so simple at this point. Nonetheless, I will do as you say and we'll see what shows up.

      Brian

      Comment


      • #4
        Which assertion failed? Perhaps the app.id is null immediately after the save. I think it doesn't get updated until after a flush. Try changing the app.save() to app.save(flush: true) and running the test again.

        Comment


        • #5
          You might also want to check out my series of posts on GORM, which will help explain these kinds of issues:

          http://blog.springsource.com/2010/06...otchas-part-1/

          The first part deals with saving domain instances.

          Comment


          • #6
            no constraints = NOT NULL

            OK, so none of the recommended approaches, for which I am nonetheless grateful to Peter and Burt, actually showed what was going on. Since I used Grails to create the tables in Oracle (by setting dbCreate = "create-drop") in our development environment, I decided to see if there were NOT NULL columns. Sure enough, all the columns which had no constraints were defined in ORACLE as NOT NULL.

            I added nullable:true to all the properties that the test was ignoring (there were a lot more than the four properties in the simple test for an Application), and the test passed.

            If I run the Grails app, and leave a NOT NULL column empty, I get:

            Code:
            java.sql.BatchUpdateException: ORA-01400: cannot insert NULL into ("owner"."APPQUEST_APPLICATIONS"."APPLICATION_DESCRIPTION")
            I get no such error in an integration test. Is there a reason, or a way that I can capture that?

            Brian

            Comment


            • #7
              ORA-01400 is an Oracle error, i.e. it's thrown by the database. Integration tests are run inside a transaction by default and that transaction is rolled back at the end of the test. That means the data is never committed by the database, and so the database validation is not triggered.

              If the problem was a simple nullable constraint violation, Burt's suggestion should have helped. Was the 'errors' object empty? One thing I would point out is that hasErrors() is a method, so it requires the parentheses in this case.

              Comment


              • #8
                The "errors" object was indeed empty. There was no way to get a hint of what was going on without looking at the database tables, and using deduction. It would have been nice if the errors object had something, anything at all that would point me in the right direction.

                On the other hand, all is well, all shall be well, and all manner of things shall be well. The app is working at the moment.

                Thanks again for your assistance.

                Brian

                Comment

                Working...
                X