Giter Club home page Giter Club logo

gorm-hibernate5's Introduction

gorm-hibernate5's People

Contributors

acanby avatar andrewcanby-finocomp avatar aulea avatar benrhine avatar billgonemad avatar bkoehm avatar chrislmartin avatar christilden avatar daraii avatar dependabot-preview[bot] avatar dependabot[bot] avatar dpcasady avatar erichelgeson avatar felixscheinost avatar fynjy avatar goeh avatar graemerocher avatar guillermocalvo avatar ilopmar avatar jameskleeh avatar joemccall86 avatar longwa avatar matrei avatar puneetbehl avatar renovate-bot avatar renovate[bot] avatar sdelamo avatar tkvw avatar ysb33r avatar zyro23 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gorm-hibernate5's Issues

Dynamic method countByStuff() not working properly when used with where queries of domain classes

Dear Grails developer team,

I would like to report the following issue: When running a dynamic countByDynamicStuffBlah on a static where query of a domain class, the where code is not transformed into SQL properly. However running the same on a named query instead of a where query OR running a findByDynamicStuffBlah on the where query works correctly.

FYI: I have re-filed the issue in this tracker because it is rather a Gorm/Hibernate issue than a grails-core issue.

Steps to Reproduce

  1. Download the example application: countby.zip
  2. Unpack the zip archive somewhere
  3. Go to the new folder "countby"
  4. If you use gvm, type: gvm use grails 3.2.0.RC1
  5. Type: grails run-app
  6. Browse to http://localhost:8080/
  7. Open the following files: Bootstrap.groovy (puts together the test files), Book.groovy (the Book domain class with a where query and a named query), BookController.groovy (executes the tests and shows the results via println() )
  8. Select the Book controller in the UI (book/index)
  9. Watch the grails log and compare it to my attached log.txt

Expected Behaviour

countBy should work the same way as findBy on where queries, so if findBy returns 2 objects, so should countBy.

Actual Behaviour

countByAuthor works with the named query, however not with the where query. logSql is set to true in the project, so you can see that the named query generates "this_.is_scientific=? and this_.author_id=?", whereas "this_.is_scientific=?" is omitted in the where query.

Here is the log i got on my machine: log.txt

Have a look at the SQL statements on these lines:

  • 49: findByAuthor on where query => is_scientific condition PRESENT
  • 52: findByAuthor on named query => is_scientific condition PRESENT
  • 55: countByAuthor on where query => is_scientific condition MISSING
  • 58: countByAuthor on named query => is_scientific condition PRESENT

Environment Information

  • Operating System:
    myuser@mybox:$ cat /etc/issue
    Ubuntu 16.04.1 LTS \n \l
    myuser@mybox:
    $ uname -a
    Linux mybox 4.4.0-36-generic #55-Ubuntu SMP Thu Aug 11 18:01:55 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
  • Grails Version:
    myuser@mybox:~$ grails -v
    Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=1024m; support was removed in 8.0
    | Grails Version: 3.2.0.RC1
    | Groovy Version: 2.4.7
    | JVM Version: 1.8.0_101
  • JDK Version:
    myuser@mybox:~$ java -version
    java version "1.8.0_101"
    Java(TM) SE Runtime Environment (build 1.8.0_101-b13)
    Java HotSpot(TM) 64-Bit Server VM (build 25.101-b13, mixed mode)

Example Application

  • see zip file with example application

Futher facts

  • It all still worked in Grails 2.5.0 with hibernate4
  • The same error happens with PostgreSQL databases, not just h2

Thank you in advance for having a look at this issue!

Continuation to #62

In continuation to issue #62

@graemerocher within same transaction, session, if an object is updated and saved (irrespective whether it is flushed or not) if we query for the same object we should be able to get the dirty instance back. Right?

My understanding:

For get, load within the same transaction: We look at session first, if not found then second level cache if not found then hit DB to retrieve it.
For queries: We hit DB first and retrieve the list and then include/update matching objects from second level cache and then from current session.
I validated this understanding with spring-hibernate(5) project and it looks to be valid.
In fact I tried with grails 3.2.9 - and works there too. But not in grails 3.3.1

Does grails, gorm work differently?

Spring-hiberbnate:
User n = new User();
n.setName(name);
n.setEmail(email);
Session session = sessionFactory.getCurrentSession();
session.save(user);
Criteria c = session.createCriteria(User.class);
c.add(Restrictions.eq("name", user.getName()));
List results = c.list();
System.out.println("Size: " + results.size());

grails-gorm (Works in 3.2.9, but not in 3.3.1):
TestObject o = new TestObject()
o.name = "name_here"
o.description = "desc_here"
o.save()
println "START createCriteria--------------"
def c = TestObject.createCriteria()
def results = c.list {
eq("name", o.name)
}
results?.each {
println it.name + " " + it.description
}
println "END createCriteria--------------"

[Bug]: Invalid update of `LAST_UPDATED` prop

Not sure if this is actually used, but this code assumes that the LAST_UPDATED property is of type java.util.Date, so this will error if another type is used.

PersistentProperty lastUpdated = targetEntity.getPropertyByName(GormProperties.LAST_UPDATED);
if(lastUpdated != null && targetEntity.getMapping().getMappedForm().isAutoTimestamp()) {
properties.put(GormProperties.LAST_UPDATED, new Date());
}

Race condition

I'm having a weird error with a plugin, but I think it is a race condition in HibernateMappingContextConfiguration, long story short, it gives me a NullPointerException on the line 266 ((ServiceRegistryImplementor)serviceRegistry).destroy();

From what I see, the SessionFactoryObserver is set before the serviceRegistry is created therefore leading to a NPE in some cases, and so my app runs some times and other times it flops with NPE. I don't really understand why sessionFactoryImple.Close() is being called, and this may be another problem.

        setSessionFactoryObserver(new SessionFactoryObserver() {
            private static final long serialVersionUID = 1;
            public void sessionFactoryCreated(SessionFactory factory) {}
            public void sessionFactoryClosed(SessionFactory factory) {
                ((ServiceRegistryImplementor)serviceRegistry).destroy();
            }
        });

        StandardServiceRegistryBuilder standardServiceRegistryBuilder = createStandardServiceRegistryBuilder(bootstrapServiceRegistry)
                                                                                    .applySettings(getProperties());

        StandardServiceRegistry serviceRegistry = standardServiceRegistryBuilder.build();
        sessionFactory = super.buildSessionFactory(serviceRegistry);
        this.serviceRegistry = serviceRegistry;

Am I wrong thinking this may produce a race condition?

Here is more detail of issue mathpere/grails-hibernate-search-plugin#33

Grails firing find and save query when performing domain.save()

I have a piece of code in Grails2x with sql database. I have a table which is mapped to a domain. It was working fine with grails2x but as I update it to grails 3.2.9 , when I perform domain.save() it fires find query in hibernate and then update query and finally it fails.
Below I've attached error log:

org.springframework.orm.hibernate5.HibernateOptimisticLockingFailureException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1; nested exception is org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1

One more thing I will like to add for those table whose data type is varchar, domain.save() is working fine, but the table with column nvarchar type is giving above error.

A transactional problem with Multi-Datasource

Hi,

When I have a single datasource, the code next work properly

    @Transactional
    boolean saveUser(User user) {
        user.setRoleId(1L);
        user.setCode("userCode");
        user.setUserName("userName");
        user.save(flush:true);
        return true;
    }

But when I have multi-datasource, the code before can't work properly, and throw an exception :

org.hibernate.HibernateException: No Session found for current thread
	at org.grails.orm.hibernate.GrailsSessionContext.currentSession(GrailsSessionContext.java:116) ~[grails-datastore-gorm-hibernate5-6.0.3.RELEASE.jar:na]
	at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:699) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
	at org.grails.orm.hibernate.cfg.GrailsHibernateUtil.setObjectToReadWrite(GrailsHibernateUtil.java:325) ~[grails-datastore-gorm-hibernate5-6.0.3.RELEASE.jar:na]
	at org.grails.orm.hibernate.cfg.GrailsHibernateUtil$setObjectToReadWrite.call(Unknown Source) ~[na:na]
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) ~[groovy-2.4.7.jar:2.4.7]
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) ~[groovy-2.4.7.jar:2.4.7]
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:133) ~[groovy-2.4.7.jar:2.4.7]
	at org.grails.orm.hibernate.HibernateGormInstanceApi.setObjectToReadWrite(HibernateGormInstanceApi.groovy:133) ~[grails-datastore-gorm-hibernate5-6.0.3.RELEASE.jar:na]
	at org.grails.orm.hibernate.AbstractHibernateGormInstanceApi.save(AbstractHibernateGormInstanceApi.groovy:136) ~[grails-datastore-gorm-hibernate-core-6.0.3.RELEASE.jar:na]
	at org.grails.datastore.gorm.GormEntity$Trait$Helper.save(GormEntity.groovy:151) ~[grails-datastore-gorm-6.0.3.RELEASE.jar:na]
	at org.grails.datastore.gorm.GormEntity$Trait$Helper$save.call(Unknown Source) ~[na:na]
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) ~[groovy-2.4.7.jar:2.4.7]
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) ~[groovy-2.4.7.jar:2.4.7]
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:133) ~[groovy-2.4.7.jar:2.4.7]
	at com.minstone.industry.app.provider.multidsprovider.domain.User.save(User.groovy) ~[classes/:na]
	at com.minstone.industry.app.provider.multidsprovider.domain.User.save(User.groovy) ~[classes/:na]
	at org.grails.datastore.gorm.GormEntity$save.call(Unknown Source) ~[na:na]
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) ~[groovy-2.4.7.jar:2.4.7]
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) ~[groovy-2.4.7.jar:2.4.7]
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) ~[groovy-2.4.7.jar:2.4.7]
	at com.minstone.industry.app.provider.multidsprovider.service.UserService.saveUser(UserService.groovy:29) ~[classes/:na]
        ......

And I have to change the code :

    boolean saveUser(User user) {
        User.withTransaction{
            user.setRoleId(1L);
            user.setCode("userCode");
            user.setUserName("userName");
            user.save(flush:true);
        }
        return true;
    }

Do you have any idea to solve this problem ?

Exception in thread "Thread-8" BUG! exception in phase 'semantic analysis' in source unit

Getting this exception in Gorm 6.1 with Grails 3.3.2:

    Exception in thread "Thread-8" BUG! exception in phase 'semantic analysis' in source unit '/Users/emmanuj/projects/cleena/demo/src/main/groovy/com/emmanuj/cleena/UserService.groovy' unexpected NullpointerException
            at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1070)
            at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:603)
            at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:581)
            at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:558)
            at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:537)
            at grails.boot.GrailsApp.compileGroovyFile(GrailsApp.groovy:313)
            at grails.boot.GrailsApp.recompile(GrailsApp.groovy:299)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.lang.reflect.Method.invoke(Method.java:498)
            at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1427)
            at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
            at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
            at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:384)
            at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
            at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:69)
            at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:52)
            at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:154)
            at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:182)
            at grails.boot.GrailsApp$_enableDevelopmentModeWatch_closure1.doCall(GrailsApp.groovy:240)
            at grails.boot.GrailsApp$_enableDevelopmentModeWatch_closure1.doCall(GrailsApp.groovy)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.lang.reflect.Method.invoke(Method.java:498)
            at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1427)
            at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
            at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
            at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
            at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
            at groovy.lang.Closure.call(Closure.java:414)
            at groovy.lang.Closure.call(Closure.java:408)
            at groovy.lang.Closure.run(Closure.java:495)
            at java.lang.Thread.run(Thread.java:748)
    Caused by: java.lang.NullPointerException
            at org.grails.datastore.gorm.services.implementers.AbstractDetachedCriteriaServiceImplementor.doImplement(AbstractDetachedCriteriaServiceImplementor.groovy:79)
            at org.grails.datastore.gorm.services.implementers.AbstractReadOperationImplementer.implement(AbstractReadOperationImplementer.groovy:62)
            at org.grails.datastore.gorm.services.transform.ServiceTransformation.visitAfterTraitApplied(ServiceTransformation.groovy:278)
            at org.grails.datastore.gorm.transform.AbstractTraitApplyingGormASTTransformation.visit(AbstractTraitApplyingGormASTTransformation.groovy:52)
            at org.grails.datastore.gorm.transform.AbstractTraitApplyingGormASTTransformation.visit(AbstractTraitApplyingGormASTTransformation.groovy:42)
            at org.grails.datastore.gorm.transform.AbstractGormASTTransformation.visit(AbstractGormASTTransformation.groovy:59)
            at org.codehaus.groovy.transform.ASTTransformationVisitor.visitClass(ASTTransformationVisitor.java:134)
            at org.codehaus.groovy.transform.ASTTransformationVisitor$2.call(ASTTransformationVisitor.java:178)
            at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1065)
            ... 34 more

Steps To Reproduce

  1. Create a new Grails 3.3.2 project

  2. Create a domain class called User like below:

     import grails.compiler.GrailsCompileStatic
    
     @GrailsCompileStatic
     class User {
    
         String name
         static constraints = {
         }
     }
    
  3. And the Following Gorm Data Services Interface and class:

     package com.emmanuj.cleena
    
     /**
      * DataService interface for user domain
      */
     interface IUserService {
         User get(Serializable id)
         List<User> list(Map args)
         Long count()
         void delete(Serializable id)
         User save(User user)
     }
    

And an abstract class implementation:

    @Slf4j
    @Service(User)
    abstract class UserService implements IUserService {
        def grailsApplication
        List<User> search(User currentUser, long radius, int offset, int max){
            return []
        }

        def getZipcodes(String zipCode, long radius) {
            return []
        }

    }
  1. Run your grails app from the interactive prompt.
  2. Make a change to UserService
  3. Exception/Crash during recompile.

MetadataContributor not injected inside HibernateConnectionSourceFactory

i'm trying to use org.hibernate.boot.spi.MetadataContributor to add some hibernate filter definition, and want to inject it inside HibernateConnectionSourceFactory using spring bean, but seems does not work.

I created a small grails plugin to illustrate this issue https://github.com/bdbogjoe/grails-metadata-contributor

When you run this plugin using grails run-app you will get output :

*** Metadata contributor from context : grails.metadata.contributor.MetadataContributorImpl@3c910acd
*** Contributor set to factory : null

The second line should return the same object as the first line

Using multi-tenant discriminator mode, IN queries are broken

I have an example app to show the issue. Just start it and bootstrap will fail. I have 3 levels of objects using multi-tenant support (subdomain based). Anyhow when I do a query from a child object for related objects I get a SQL error that one of the parameters (the IN statement criteria) is missing.

Caused by: org.h2.jdbc.JdbcSQLException: Parameter "#2" is not set; SQL statement:
select this_.id as id1_3_0_, this_.version as version2_3_0_, this_.tenant_id as tenant_i3_3_0_, this_.date_created as date_cre4_3_0_, this_.last_updated as last_upd5_3_0_, this_.name as name6_3_0_, this_.activity as activity7_3_0_, this_.date_trashed as date_tra8_3_0_ from contact_activity this_ where this_.date_trashed=? and this_.id in (?) [90012-193]
	at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
	at org.h2.message.DbException.get(DbException.java:179)
	at org.h2.message.DbException.get(DbException.java:155)
	at org.h2.expression.Parameter.checkSet(Parameter.java:81)
	at org.h2.command.Prepared.checkParameters(Prepared.java:164)
	at org.h2.command.CommandContainer.query(CommandContainer.java:109)
	at org.h2.command.Command.executeQuery(Command.java:201)
	at org.h2.jdbc.JdbcPreparedStatement.executeQuery(JdbcPreparedStatement.java:110)
	at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:70)
	... 88 common frames omitted

This example has a namedQuery but also I've tried where queries and regular criteria queries with the same result.

It seem to not work with the "dataSource.url" of application.yaml !

I user gorm with spring-boot .
This is my application.yaml file

dataSource:
        pooled: true
        jmxExport: true
        driverClassName: com.mysql.jdbc.Driver
        dialect: org.hibernate.dialect.MySQL5InnoDBDialect
        url:   jdbc:mysql://127.0.0.1:3306/gorm
        username: root
        password: 123456
        logSql: true

hibernate:
    cache:
        queries: false
        use_second_level_cache: true
        use_query_cache: false
        region.factory_class: org.hibernate.cache.ehcache.EhCacheRegionFactory

I turn the database type to MYSQL,but is always prompt me with the error message

o.s.jdbc.support.SQLErrorCodesFactory    : SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase, Hana]

this is complete message when I boot :

Connected to the target VM, address: '127.0.0.1:59795', transport: 'socket'

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.4.1.RELEASE)

2016-10-31 16:29:24.717  INFO 13464 --- [           main] com.GroovyApplication                    : Starting GroovyApplication on WbsPool with PID 13464 (E:\workspace\IdeaProjects\spring-boot\target\classes started by Marco in E:\workspace\IdeaProjects\spring-boot)
2016-10-31 16:29:24.723  INFO 13464 --- [           main] com.GroovyApplication                    : No active profile set, falling back to default profiles: default
2016-10-31 16:29:24.821  INFO 13464 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@342bcdc: startup date [Mon Oct 31 16:29:24 CST 2016]; root of context hierarchy
2016-10-31 16:29:35.843  INFO 13464 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Overriding bean definition for bean 'hibernateProxyHandler' with a different definition: replacing [Generic bean: class [org.grails.orm.hibernate.proxy.HibernateProxyHandler]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] with [Generic bean: class [org.grails.orm.hibernate.proxy.HibernateProxyHandler]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null]
2016-10-31 16:29:35.847  INFO 13464 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Overriding bean definition for bean 'proxyHandler' with a different definition: replacing [Generic bean: class [org.grails.datastore.gorm.proxy.ProxyHandlerAdapter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] with [Generic bean: class [org.grails.datastore.gorm.proxy.ProxyHandlerAdapter]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null]
2016-10-31 16:29:35.848  INFO 13464 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Overriding bean definition for bean 'hibernateConnectionSourceFactory' with a different definition: replacing [Generic bean: class [org.grails.orm.hibernate.connections.HibernateConnectionSourceFactory]; scope=; abstract=false; lazyInit=false; autowireMode=1; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] with [Generic bean: class [org.grails.orm.hibernate.connections.HibernateConnectionSourceFactory]; scope=; abstract=false; lazyInit=false; autowireMode=1; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null]
2016-10-31 16:29:35.848  INFO 13464 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Overriding bean definition for bean 'hibernateDatastore' with a different definition: replacing [Generic bean: class [org.grails.orm.hibernate.HibernateDatastore]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] with [Generic bean: class [org.grails.orm.hibernate.HibernateDatastore]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null]
2016-10-31 16:29:35.849  INFO 13464 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Overriding bean definition for bean 'sessionFactory' with a different definition: replacing [Generic bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=hibernateDatastore; factoryMethodName=getSessionFactory; initMethodName=null; destroyMethodName=null] with [Generic bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=hibernateDatastore; factoryMethodName=getSessionFactory; initMethodName=null; destroyMethodName=null]
2016-10-31 16:29:35.849  INFO 13464 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Overriding bean definition for bean 'transactionManager' with a different definition: replacing [Generic bean: class [org.springframework.transaction.PlatformTransactionManager]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=hibernateDatastore; factoryMethodName=getTransactionManager; initMethodName=null; destroyMethodName=null] with [Generic bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=hibernateDatastore; factoryMethodName=getTransactionManager; initMethodName=null; destroyMethodName=null]
2016-10-31 16:29:35.849  INFO 13464 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Overriding bean definition for bean 'persistenceInterceptor' with a different definition: replacing [Generic bean: class [org.grails.orm.hibernate5.support.AggregatePersistenceContextInterceptor]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] with [Generic bean: class [org.grails.orm.hibernate5.support.AggregatePersistenceContextInterceptor]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null]
2016-10-31 16:29:35.850  INFO 13464 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Overriding bean definition for bean 'grailsDomainClassMappingContext' with a different definition: replacing [Generic bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=hibernateDatastore; factoryMethodName=getMappingContext; initMethodName=null; destroyMethodName=null] with [Generic bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=hibernateDatastore; factoryMethodName=getMappingContext; initMethodName=null; destroyMethodName=null]
2016-10-31 16:29:38.336  INFO 13464 --- [           main] org.hibernate.Version                    : HHH000412: Hibernate Core {5.1.0.Final}
2016-10-31 16:29:38.343  INFO 13464 --- [           main] org.hibernate.cfg.Environment            : HHH000206: hibernate.properties not found
2016-10-31 16:29:38.347  INFO 13464 --- [           main] org.hibernate.cfg.Environment            : HHH000021: Bytecode provider name : javassist
2016-10-31 16:29:38.522  INFO 13464 --- [           main] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
2016-10-31 16:29:39.128  INFO 13464 --- [           main] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
2016-10-31 16:29:40.486  INFO 13464 --- [           main] o.h.t.schema.internal.SchemaCreatorImpl  : HHH000476: Executing import script 'org.hibernate.tool.schema.internal.exec.ScriptSourceInputNonExistentImpl@408e9513'
2016-10-31 16:29:40.738  INFO 13464 --- [           main] o.s.b.f.xml.XmlBeanDefinitionReader      : Loading XML bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml]
2016-10-31 16:29:40.879  INFO 13464 --- [           main] o.s.jdbc.support.SQLErrorCodesFactory    : SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase, Hana]
2016-10-31 16:29:41.549  INFO 13464 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2016-10-31 16:29:41.631  INFO 13464 --- [           main] com.GroovyApplication                    : Started GroovyApplication in 18.398 seconds (JVM running for 20.312)
2016-10-31 16:29:41.633  INFO 13464 --- [       Thread-2] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@342bcdc: startup date [Mon Oct 31 16:29:24 CST 2016]; root of context hierarchy
2016-10-31 16:29:41.636  INFO 13464 --- [       Thread-2] o.s.j.e.a.AnnotationMBeanExporter        : Unregistering JMX-exposed beans on shutdown
2016-10-31 16:29:41.636  INFO 13464 --- [       Thread-2] .SchemaDropperImpl$DelayedDropActionImpl : HHH000477: Starting delayed drop of schema as part of SessionFactory shut-down'
Disconnected from the target VM, address: '127.0.0.1:59795', transport: 'socket'

hibernate-5.1+ SQLException: PooledConnection has already been closed.

using hibernate-5.1 and above, we see frequent DEBUG logs of java.sql.SQLException: PooledConnection has already been closed..

https://jira.spring.io/browse/SPR-14548 looks related. spring adjusts the connection release-/handling-mode to the variants of "on_close" that spring wants/needs.
i think gorm does not use LocalSessionFactoryBuilder (ref. spring-projects/spring-framework@fad931d) and the hibernate defaults are used which are different.

adding the corresponding hibernate config properties makes the excessive DEBUG logs go away:

# hibernate-5.1.x:
hibernate:
    connection:
        release_mode: ON_CLOSE

# hibernate-5.2.x:
hibernate:
    connection:
        handling_mode: DELAYED_ACQUISITION_AND_HOLD

would be great if gorm applies those by default, too.

thanks, zyro

Data Service JPA-QL Queries not working as expected on join

Given a simple example modeled after the documentation, the return value is returning both Book and Author paired (and somehow breaking the generics return val, didn't know that was possible). This issue seems to be specific to spring-boot non-grails app. I tried an example in grails and it worked as expected.

class Book { 
 String name
 Author author
}

class Author {
 String lastName, firstName
}

@Service(Book)
interface BookService {
 @Query("""
FROM ${Book book} 
 JOIN ${Author author = book.author} 
WHERE $author.lastName = $lastName
""")
  List<Book> findBooksByAuthorLastName(String lastName)
}

What's happening is that when I try and do this:

BookService.findBooksByAuthorLastName("Hemmingway").each{ Book book-> println book.name }

This is throwing a class cast exception. When I review the return value it's [ [Book, Author], [Book, Author]...]

Also get an invalid query exception if I try and specify SELECT $book

bidirectional relation save exception

Given two entities:

 class User {
      Address address    

      static constraints = {
         address cascade:'all'
     }
 }
 class Address {
      User user 
      Date dateCreated
      Date lastUpdated

      static constraints = {
         user nullable:true
     }
 }

And calling:

 new User(address:new Address())

Grails will throw an Exception:
org.springframework.dao.InvalidDataAccessApiUsageException: object references an unsaved transient instance - save the transient instance before flushing: test.User; nested exception is org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: test.User

This only happens if you have the dateCreated and lastUpdated properties defined.
I've created a test project to see this behaviour:
https://github.com/tkvw/issue-bidirectional

Furthermore: why does grails think this is a bidirectional relationship?

Adding a new data source at runtime wipes the default data source's database

Hi, I am using the ConnectionSources API to add a data source at runtime with the addConnectionSource method. The code looks something like this:

    def sourcesAPI = hibernateDatastore.getConnectionSources()
    def ds = sourcesAPI.getConnectionSource("${dbName}Source")
    if (ds == null) {
      ds = sourcesAPI.addConnectionSource("${dbName}Source",
        [pooled         : true,
         dbCreate       : "create-drop",
         logSql         : false,
         formatSql      : true,
         url            : "${POSTGRES_URL_BASE}${dbName}",
         dialect        : "org.hibernate.dialect.PostgreSQLDialect",
         driverClassName: POSTGRES_DRIVER_CLASS_NAME,
         username       : username,
         password       : password])
    }

Even though I specify a url configuration parameter, addConnectionSource ends up using the default data source and wipes the database.

I'm guessing there must be a bug in configuration processing.

6.0.5 - HibernateConnectionSourceSettings.HibernateSettings not correctly initialized

trying to use application.yml

hibernate:
    configClass: foo.bar.MyHibernateMappingContextConfiguration

in a grails 3.2.4 (gorm-6.0.5) app, that still resulted in default HibernateMappingContextConfiguration being configured.

debugging to https://github.com/grails/gorm-hibernate5/blob/v6.0.5/grails-datastore-gorm-hibernate5/src/main/groovy/org/grails/orm/hibernate/connections/HibernateConnectionSourceFactory.java#L92 you can see that:

  • HibernateConnectionSourceSettings.HibernateSettings is populated as a map correctly, containing the entrySet ["configClass": "foo.bar.MyHibernateMappingContextConfiguration"], but
  • HibernateConnectionSourceSettings.HibernateSettings.configClass property is null (which is returned by hibernateSettings.getConfigClass()).

so i guess there is something missing with the initialization that sets (or rather not sets) the HibernateSettings properties?

how to hot-deploy GORM project in weblogic?

i have a spring boot project using GORM & groovy, deploy in weblogic 12c (12213).
Weblogic throw frozen class RuntimeException,when we update project (hot-deploy) from weblogic console. How to fix it to support hot-deploy?

<Error> <Deployer> <BEA-149265> <Failure occurred in the execution of deployment request with ID "5768901220916096" for task "9" on [partition-name: DOMAIN]. Error is: "weblogic.application.ModuleException: java.lang.RuntimeException: org.grails.orm.hibernate.proxy.GroovyAwareJavassistLazyInitializer: frozen class (cannot edit)" weblogic.application.ModuleException: java.lang.RuntimeException: org.grails.orm.hibernate.proxy.GroovyAwareJavassistLazyInitializer: frozen class (cannot edit) at weblogic.application.internal.ExtensibleModuleWrapper.start(ExtensibleModuleWrapper.java:140) at weblogic.application.internal.flow.ModuleListenerInvoker.start(ModuleListenerInvoker.java:124) at weblogic.application.internal.flow.ModuleStateDriver$3.next(ModuleStateDriver.java:233) at weblogic.application.internal.flow.ModuleStateDriver$3.next(ModuleStateDriver.java:228) at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:45) Truncated. see log file for complete stacktrace Caused By: java.lang.RuntimeException: org.grails.orm.hibernate.proxy.GroovyAwareJavassistLazyInitializer: frozen class (cannot edit) at javassist.ClassPool.checkNotFrozen(ClassPool.java:610) at javassist.ClassPool.makeClass(ClassPool.java:852) at org.grails.orm.hibernate.proxy.ProxyFactorySupport.<clinit>(ProxyFactorySupport.groovy:38) at org.grails.orm.hibernate.cfg.GrailsHibernateUtil.buildProxyFactory(GrailsHibernateUtil.java:418) at org.grails.orm.hibernate.proxy.GroovyAwarePojoEntityTuplizer.buildProxyFactory(GroovyAwarePojoEntityTuplizer.java:45)

bug: no update on child values

I found a bug on gormVersion=6.1.7.RELEASE
I updated it from 6.1.5.RELEASE where it also happened

example code:

 Product.withTransaction {
            Pro2t domainObject= Pro2t .get(id)
                //domainObject.internal= "something1"  // this level updates are ok
                domainObject.child.interna2 = "something2"  // second level does not triguer update
                domainObject.save(flush: true, validate: false)
        }

Multi-tenancy Mode: Schema, java.sql.SQLException: PooledConnection has already been closed

Ours is a multitenant application running in SCHEMA mode on Postgres database.
We are continuously facing java.sql.SQLException: PooledConnection has already been closed issue.

Here is the stacktrace for it:

ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper - PooledConnection has already been closed.
ERROR org.grails.web.errors.GrailsExceptionResolver - SQLException occurred when processing request: [GET] /login/auth
PooledConnection has already been closed.. Stacktrace follows:
org.springframework.jdbc.UncategorizedSQLException: Hibernate operation: could not prepare statement; uncategorized SQLException for SQL [select this_.id as id1_84_0_, this_.version as version2_84_0_, this_.date_created as date_cre3_84_0_, this_.logo as logo4_84_0_, this_.organization as organiza5_84_0_, this_.username as username6_84_0_, this_.password as password7_84_0_, this_.status as status8_84_0_, this_.is_infra_provider as is_infra9_84_0_, this_.domain as domain10_84_0_, this_.identifier as identif11_84_0_, this_.email as email12_84_0_ from public.tenant this_ where this_.domain=? limit ?]; SQL state [null]; error code [0]; PooledConnection has already been closed.; nested exception is java.sql.SQLException: PooledConnection has already been closed.
        at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:84)
        at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
        at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
        at org.grails.orm.hibernate.GrailsHibernateTemplate.convertJdbcAccessException(GrailsHibernateTemplate.java:723)
        at org.grails.orm.hibernate.GrailsHibernateTemplate.convertHibernateAccessException(GrailsHibernateTemplate.java:711)
        at org.grails.orm.hibernate.GrailsHibernateTemplate.doExecute(GrailsHibernateTemplate.java:302)
        at org.grails.orm.hibernate.GrailsHibernateTemplate.execute(GrailsHibernateTemplate.java:242)
        at org.grails.orm.hibernate.GrailsHibernateTemplate.executeWithNewSession(GrailsHibernateTemplate.java:149)
        at org.grails.orm.hibernate.GrailsHibernateTemplate.executeWithExistingOrCreateNewSession(GrailsHibernateTemplate.java:208)
        at org.grails.orm.hibernate.AbstractHibernateDatastore.withNewSession(AbstractHibernateDatastore.java:362)
        at grails.gorm.multitenancy.Tenants$_withId_closure1.doCall(Tenants.groovy:218)
        at grails.gorm.multitenancy.Tenants$CurrentTenant.withTenant(Tenants.groovy:318)
        at grails.gorm.multitenancy.Tenants.withId(Tenants.groovy:196)
        at grails.gorm.multitenancy.Tenants.withId(Tenants.groovy:166)
        at grails.plugin.springsecurity.LoginController.auth(LoginController.groovy:62)
        at org.grails.core.DefaultGrailsControllerClass$MethodHandleInvoker.invoke(DefaultGrailsControllerClass.java:223)
        at org.grails.core.DefaultGrailsControllerClass.invoke(DefaultGrailsControllerClass.java:188)
        at org.grails.web.mapping.mvc.UrlMappingsInfoHandlerAdapter.handle(UrlMappingsInfoHandlerAdapter.groovy:90)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
        at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
        at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)
        at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55)
        at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
        at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
        at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
        at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:317)
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115)
        at grails.plugin.springsecurity.web.UpdateRequestContextHolderExceptionTranslationFilter.doFilter(UpdateRequestContextHolderExceptionTranslationFilter.groovy:64)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter.doFilter(GrailsAnonymousAuthenticationFilter.groovy:53)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:150)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter.doFilter(MutableLogoutFilter.groovy:62)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at grails.plugin.springsecurity.web.SecurityRequestHolderFilter.doFilter(SecurityRequestHolderFilter.groovy:58)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
        at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
        at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
        at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
        at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
        at org.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:77)
        at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
        at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
        at org.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:67)
        at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
        at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
        at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
        at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
        at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
        at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
        at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
        at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
        at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
        at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
        at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
        at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
        at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
        at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
        at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
        at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
        at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
        at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
        at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
        at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
        at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
        at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:285)
        at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:264)
        at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
        at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:175)
        at io.undertow.server.Connectors.executeRootHandler(Connectors.java:209)
        at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:802)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:748)
Caused by: java.sql.SQLException: PooledConnection has already been closed.
        at org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy$LazyConnectionInvocationHandler.invoke(LazyConnectionDataSourceProxy.java:376)
        at org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy$TransactionAwareInvocationHandler.invoke(TransactionAwareDataSourceProxy.java:240)
        at org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy$TransactionAwareInvocationHandler.invoke(TransactionAwareDataSourceProxy.java:240)
        at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:146)
        at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:172)
        at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:148)
        at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1934)
        at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1903)
        at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1881)
        at org.hibernate.loader.Loader.doQuery(Loader.java:925)
        at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:342)
        at org.hibernate.loader.Loader.doList(Loader.java:2622)
        at org.hibernate.loader.Loader.doList(Loader.java:2605)
        at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2434)
        at org.hibernate.loader.Loader.list(Loader.java:2429)
        at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:109)
        at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1787)
        at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:363)
        at org.grails.orm.hibernate.query.AbstractHibernateQuery.singleResultViaListCall(AbstractHibernateQuery.java:801)
        at org.grails.orm.hibernate.query.AbstractHibernateQuery.singleResult(AbstractHibernateQuery.java:791)
        at org.grails.datastore.gorm.finders.AbstractFindByFinder.invokeQuery(AbstractFindByFinder.java:35)
        at org.grails.datastore.gorm.finders.AbstractFindByFinder$1.doInSession(AbstractFindByFinder.java:29)
        at org.grails.datastore.mapping.core.DatastoreUtils.execute(DatastoreUtils.java:319)
        at org.grails.datastore.gorm.finders.AbstractFinder.execute(AbstractFinder.java:42)
        at org.grails.datastore.gorm.finders.AbstractFindByFinder.doInvokeInternal(AbstractFindByFinder.java:27)
        at org.grails.datastore.gorm.finders.DynamicFinder.invoke(DynamicFinder.java:252)
        at org.grails.datastore.gorm.finders.DynamicFinder.invoke(DynamicFinder.java:390)
        at org.grails.datastore.gorm.GormStaticApi.methodMissing(GormStaticApi.groovy:172)
        at org.grails.datastore.gorm.GormEntity$Trait$Helper.staticMethodMissing(GormEntity.groovy:757)
        at grails.plugin.springsecurity.LoginController$_auth_closure1.doCall(LoginController.groovy:63)
        at grails.gorm.multitenancy.Tenants$_withId_closure1$_closure3.doCall(Tenants.groovy:225)
        at org.grails.orm.hibernate.GrailsHibernateTemplate$1.doInHibernate(GrailsHibernateTemplate.java:152)
        at org.grails.orm.hibernate.GrailsHibernateTemplate.doExecute(GrailsHibernateTemplate.java:298)
        ... 83 common frames omitted

Some pointers on this:

  1. Production environment Configuration:
---
hibernate:
    cache:
        queries: false
        use_second_level_cache: false
        use_query_cache: false
        region.factory_class: 'org.hibernate.cache.ehcache.EhCacheRegionFactory'

dataSource:
    pooled: true
    jmxExport: true
    driverClassName: org.h2.Driver
    username: sa
    password:

environments:
    production:
        dataSource:
            dbCreate: none
            pooled: true
            jmxExport: true
            driverClassName: 'org.postgresql.Driver'
            dialect: net.kaleidos.hibernate.PostgresqlExtensionsDialect
            username: 'root'
            password: 'root'
            url:  'jdbc:postgresql://someHostname:5432/database'
            logSql: true
	    schemaHandler: flint.forms.TenantSchemaHandler
            properties:
                jmxEnabled: true
                initialSize: 5
                maxActive: 50
                minIdle: 5
                maxIdle: 25
                maxWait: 10000
                maxAge: 600000
                timeBetweenEvictionRunsMillis: 5000
                minEvictableIdleTimeMillis: 60000
                validationQuery: SELECT 1
                validationQueryTimeout: 3
                validationInterval: 15000
                testOnBorrow: true
                testWhileIdle: true
                testOnReturn: false
                jdbcInterceptors: ConnectionState
                defaultTransactionIsolation: 2 # TRANSACTION_READ_COMMITTED
           
---
grails:
    gorm:
        multiTenancy:
            mode: SCHEMA
            tenantResolverClass: <packageName.className>

2. Environment Information:

Operating System: Ubuntu 16.04/CentOS 7
GORM Version: 6.1.4.RELEASE
Grails Version: 3.2.10
JDK Version: 1.8

3. Libraries Included:

org.grails:grails-datastore-web:6.0.11.RELEASE"
'org.grails', name: 'grails-datastore-gorm-async', version: '6.1.4.RELEASE'
org.postgresql:postgresql:9.4.1212.jre7
org.grails.plugins:postgresql-extensions:5.1.0
org.grails.plugins:hibernate5:6.1.4
org.hibernate:hibernate-core:5.1.2.Final
org.hibernate:hibernate-ehcache:5.1.2.Final
org.hibernate:hibernate-java8:5.1.2.Final
org.springframework.boot:spring-boot-starter-tomcat

Gorm 6.1.x - Domain class implementing an interface fails to start with MappingException

I have a simple Grails 3.2.9 app, with a single domain class with two properties using the following settings (gradle.properties)

grailsVersion=3.2.9
gormVersion=6.1.3.RELEASE
gradleWrapperVersion=3.4.1

Under src/groovy I have an interface defined:

interface ObjectId<T> extends Serializable {
    T getId()
    void setId(T id)
}

The domain object implements this interface:

class TestDomain implements ObjectId<Long> {

    Long id
    String name
    String description

    static constraints = {
    }
}

The application fails to start with the error

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.grails.orm.hibernate.HibernateDatastore]: Constructor threw exception; nested exception is org.hibernate.MappingException: identifier mapping has wrong number of columns: gormtest.TestDomain type: object

It doesn't make any difference if I remove the id property from the domain class, but if I change the gorm version to 6.0.11 the application starts without error.

Repo with project demonstrating the error can be found at:

https://github.com/davidbairdala/gorm6-errordemo

HibernateSpec seems not using environment dataSource config.

Grails version: 3.3.2
GORM version: 6.1.8.RELEASE

Reproduce script:

#!/bin/bash

grails create-app hibernateSpecSpec
cd hibernateSpecSpec
sed -i "/    driverClassName: org.h2.Driver/a \ \ \ \ url: 'jdbc:h2:mem:defaultDb'" grails-app/conf/application.yml
mkdir -p src/test/groovy/test
cat > src/test/groovy/test/HibernateSpecSpec.groovy <<EOF
package test

import grails.test.hibernate.HibernateSpec
import org.grails.orm.hibernate.HibernateDatastore

class HibernateSpecSpec extends HibernateSpec {
    void "HibernateSpecSpec should work"() {
        expect:
        hibernateDatastore.dataSource.connection.metaData.URL == 'jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE'
    }
}
EOF

./grailsw test-app

Here is the test report:

Condition not satisfied:

hibernateDatastore.dataSource.connection.metaData.URL == 'jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE'
|                  |          |          |        |   |
|                  |          |          |        |   false
|                  |          |          |        |   56 differences (20% similarity)
|                  |          |          |        |   jdbc:h2:mem:(d)e(fault-----------------------------)D(b--------------------)
|                  |          |          |        |   jdbc:h2:mem:(t)e(stDb;MVCC=TRUE;LOCK_TIMEOUT=10000;)D(B_CLOSE_ON_EXIT=FALSE)
|                  |          |          |        jdbc:h2:mem:defaultDb
|                  |          |          dbMeta3: conn9: url=jdbc:h2:mem:defaultDb user=SA
|                  |          Transaction-aware proxy for target Connection [Transaction-aware proxy for target Connection [DisposableConnectionFacade[null]]]
|                  org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy@713e5072
HibernateDatastore: DEFAULT

	at test.HibernateSpecSpec.HibernateSpecSpec should work(HibernateSpecSpec.groovy:9)

docs - multi-datasource config inconsistency

configuring two dataSources,

dataSource:
    # primary dataSource config ("dataSource")
dataSources:
    secondary:
        # secondary dataSource config ("dataSource_secondary")

is the correct format while

indicate that the correct format is:

dataSources:
    dataSource:
        # primary dataSource config ("dataSource")
    secondary:
        # secondary dataSource config ("dataSource_secondary")

Docs: outsideGrails.adoc

A bit of context. I'm trying to put a basic sample project together (which probably will lead to a blog) about a standalone GORM & Hibernate 5. The approach to it is from the viewpoint of someone who knows nothing about Grails or Spring, but has heard good stuff abotu GORM and what to try it out.

Based upon that I have crafted up https://github.com/ysb33r/SampleProjects/tree/GormStandalone/BasicHibernate trying to rely only on the current docs. This sample project fails because the schema is never created. Effectively there are bits of information missing from the current GORM docs in the Getting Started section, which I think is importnt to a newcomer

TableGenerator strategy on gorm-standalone/grails

For legacy compatibility reasons, I am trying to apply the code below logic on gorm-standalone 5 or grails 3.1.16 (hibernate 4) or gorm 6 / grails with hibernate 5

@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "book_generator")
@TableGenerator(name="book_generator", table="BOOK_SEQ", schema="bookstore")
@Column(name = "book_id", updatable = false, nullable = false)
private Long id;

The following code is the one I am struggling with

package helloworld

class Book {

    Integer id
    String name
    String author

    static constraints = {
        id column: 'book_id'
        name blank: false
    }
    static mapping = {
        table 'BOOKTABLE'
        version false
        // id( generator: 'hilo', params: [table: 'BOOK_SEQ', column: 'next_value', max_lo: 1, initial_value: 1, increment_size: 1 ])
        id( generator: 'table', strategy: 'enhanced-table', parameters: [name: 'table_name', value: 'BOOK_SEQ', column: 'next_value', initial_value: 1, increment_size: 1 ])

    }
}

Is it possible? How?

Thank you

Custom hibernate identity generator config no longer works in GORM 6

Upgrading to GORM 6 (Grails 3.2.0) from 5 (Grails 3.1.9), I have found that custom hibernate identity generators are no longer supported in configuration.

It throws DatastoreConfigurationException: Invalid id generation strategy for entity [...]

Source code ref:
https://github.com/grails/grails-data-mapping/blob/master/grails-datastore-gorm-hibernate-core/src/main/groovy/org/grails/orm/hibernate/cfg/HibernateMappingContext.java

Following the code appears to now only support pre-defined identity types (AUTO, SEQUENCE, etc.) and not the name of a custom identity class, which previously worked.

Config in application.groovy:

grails.gorm.default.mapping = {
    id(generator: "com.example.core.persistence.MyUUIDGenerator", type: "uuid-binary") // H2
}

The reason I have a custom identity generator is that I want to be able to assign pre-defined UUID identities to fixtures created during bootstrap if they don't already exist. Otherwise I want UUID identity to be generated as normal.

My app also uses multiple datasources, not all of which require this, so it is useful to apply this configuration via default mappings. If I knew of another way, I would not need the custom IdentifierGenerator.

For completeness, here is MyUUIDGenerator.groovy:

import org.hibernate.HibernateException
import org.hibernate.engine.spi.SessionImplementor
import org.hibernate.id.IdentifierGenerator


/**
 * Custom UUID IdentifierGenerator class that permits a pre-defined ID property value to be set during fixture creation.
 * (The stock generator does not.)
 */
class MyUUIDGenerator implements IdentifierGenerator {

    @Override
    public Serializable generate(SessionImplementor session, Object object) throws HibernateException {
        if(object.id) return object.id;
        return UUID.randomUUID();
    }

}

Root cause in stack trace from startup:

Caused by: org.grails.datastore.mapping.model.DatastoreConfigurationException: Invalid id generation strategy for entity [com.example.core.domain.Department]: com.example.core.persistence.MyUUIDGenerator
    at org.grails.orm.hibernate.cfg.HibernateMappingContext$HibernateMappingFactory.createIdentityMapping(HibernateMappingContext.java:257)
    at org.grails.orm.hibernate.cfg.HibernatePersistentEntity$1.<init>(HibernatePersistentEntity.java:37)
    at org.grails.orm.hibernate.cfg.HibernatePersistentEntity.<init>(HibernatePersistentEntity.java:35)
    at org.grails.orm.hibernate.cfg.HibernateMappingContext.createPersistentEntity(HibernateMappingContext.java:143)
    at org.grails.datastore.mapping.model.AbstractMappingContext.addPersistentEntities(AbstractMappingContext.java:270)
    at org.grails.orm.hibernate.cfg.HibernateMappingContext.<init>(HibernateMappingContext.java:72)
    at org.grails.orm.hibernate.connections.HibernateConnectionSourceFactory.buildConfiguration(HibernateConnectionSourceFactory.java:94)
    at org.grails.orm.hibernate.connections.HibernateConnectionSourceFactory.create(HibernateConnectionSourceFactory.java:85)
    at org.grails.orm.hibernate.connections.AbstractHibernateConnectionSourceFactory.create(AbstractHibernateConnectionSourceFactory.java:38)
    at org.grails.orm.hibernate.connections.AbstractHibernateConnectionSourceFactory.create(AbstractHibernateConnectionSourceFactory.java:22)
    at org.grails.datastore.mapping.core.connections.AbstractConnectionSourceFactory.create(AbstractConnectionSourceFactory.java:43)
    at org.grails.datastore.mapping.core.connections.AbstractConnectionSourceFactory.create(AbstractConnectionSourceFactory.java:31)
    at org.grails.datastore.mapping.core.connections.ConnectionSourcesInitializer.create(ConnectionSourcesInitializer.groovy:24)
    at org.grails.orm.hibernate.HibernateDatastore.<init>(HibernateDatastore.java:206)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at org.springsource.loaded.ri.ReflectiveInterceptor.jlrConstructorNewInstance(ReflectiveInterceptor.java:1075)
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:142)
    ... 44 common frames omitted

allow hibernate serviceRegistry customization

currently, the hibernate serviceRegistry is built by HibernateMappingContextConfiguration without an option to hook into the build (e.g. to register a custom service).

ref. https://github.com/grails/gorm-hibernate5/blob/master/grails-datastore-gorm-hibernate5/src/main/groovy/org/grails/orm/hibernate/cfg/HibernateMappingContextConfiguration.java#L260

it would be nice if the serviceRegistryBuilder was exposed in a way that allows to customize the builder/registry before it is built.

maybe it would be enough to pull that part out into an own protected method so we can override whe HibernateMappingContextConfiguration as the docs say but just customize the builder-related part.

as it is designed now, overriding the buildSessionFactory() method requires taking care of all the other logic inside that method, too.

Cache criteria not taken into account when cache option set in mapping

The cache setting given inside the criteria:

final criteria = Entity.createCriteria()
final result = criteria.list([:]) {
  cache(false)
}

is overwritten by the setting in the domain mapping:

class Entity {
  String field1
  static mapping = {
    cache usage: 'nonstrict-read-write', include: 'all'
  }
}

Responsible for this behavior is GrailsHibernateUtil.populateArgumentsForCriteria method and more specifically GrailsHibernateUtil.cacheCriteriaByMapping which looks into domain class mapping and if the cache is enabled there it would set it to true in the criteria. As a workaround I have to use the argument to list instead:

criteria.list([cache: false]) {
}

Thanks

Using Map/PropertyResolver for standalone GORM does not work as per documentation

The documentation states that a HibernateDatastore can be constructed via a Map or PropertyResolver:

Map configuration = [
    'hibernate.hbm2ddl.auto':'create-drop',
    'dataSource.url':'jdbc:h2:mem:myDB'
]
HibernateDatastore datastore = new HibernateDatastore( configuration, Person)

But this does not work. The above code will fail to compile. If the Map is type-casted to a PropertyResolver initialisation eventually result in a UnsupportedOperationException. Not using the class-array constructor as in the ExampleSpec code will initialise correctly, but obviously the ability to configure H2 via a Map (or using a different JDBC URL) is lost.

P.S. The fact that the doc was done from handcrafted code did not help. It would be better to include a code snippet from the examples directory.

gorm unique Constraints throw exception?

using gorm-hibernate5-spring-boot 6.0.7.RELEASE & grails-datastore-gorm 6.0.7.RELEASE in spring boot project.
application.yml config:

grails.gorm.failOnError: false
grails.gorm.autoFlush: false

Domain class :

@Entity
class Book implements GormEntity<Book> {
    String title
    static constraints = {
        title (nullable: false,size: 0..200, unique: true, blank:false)
    }
}

controller :

        def book1=new Book(title: "one");
        book1.save()
        def book2=new Book(title: "one");
        book2.save()
        println book2.errors

application throw exception:

org.h2.jdbc.JdbcSQLException: Unique index or primary key violation: "UK_G0286AG1DLT4473ST1UGEMD0M_INDEX_1 ON PUBLIC.BOOK(TITLE) VALUES (STRINGDECODE('one'), 1)"; SQL statement:
insert into book (id, version, title) values (null, ?, ?) 

why? please help me.

Tenant Discriminator Many-to-Many

Hello,
I've found an issue with a many-to-many relationship with multi-tenancy.
Let imagine that we have a User domain:

class User implements MultiTenant<User> {
     
    static hasMany = [
            departments: Department,
    ]

    static mappedBy = [
            departments: 'members'
    ]



    Long tenantId
    String someProperty

    static constraints = {
        someProperty nullable: true
    }
} 

and Department domain:

class Department implements MultiTenant<Department> {

    static hasMany = [members: User]

    static belongsTo = User

    static mappedBy = [
            members: 'departments'
    ]

    Long tenantId
    String someProperty

    static constraints = {
        someProperty nullable: true
    }
}

So: Department has many users and the user can be in many departments.

When I try to find all users that takes part in department:

User.executeQuery('from User where :department in elements(departments)', [department: department])

I've an error:

select user0_.id as id1_1_, user0_.version as version2_1_, user0_.tenant_id as tenant_i3_1_, user0_.some_property as some_pro4_1_ from user user0_ where ? = user0_.tenant_id and (? in (select department1_.department_id from user_departments department1_ where user0_.id=department1_.user_id and **? = department1_.tenant_id**))

Problem bolded.
Hibernate create the wrong query, that tries to take tenant id from a many-to-many table. I think that it's a bug and hibernate should avoid adding a filter for those cases.

Here it is a sample project for repeating issue
test-tenant.tar.gz

Error read relationship hasOne an belong

#10648
Task List

create a database with name "unabaseTest"

Steps to Reproduce

execute ./gradlew build for testing application

Expected Behaviour

The call of integration test to executing checkFather method of Pruebaservice and result expect shoul be a list with [1, 2] value, because the foreing key of class child are hija = 1 and hijaPol = 2

Actual Behaviour

but the list that return the service is [1,1] because is matching with ID of classes of child and no with foreing key

Environment Information

Operating System: ubuntu 16.04 LTS
Grails Version: 3.1.8.
JDK Version: jdk1.8.0_121
Container Version (If Applicable): Tomcat8
db mysql 5.7.8

Example Application
I will attachment a zip file with application for testing

Additional notes

When execute build the integration test run and you can see in reports th output.

BD
I will attachement image of db tables
child2table
fathertable
tablechild

expose the hibernate Metadata

rebuilding the metadata at runtime is not compatible with envers initialization

however this happens at least in:

the recommended approach to access the Metadata at runtime is to implement an Integrator that captures the fully built Metadata and exposes it.

now instead of requesting that every user/plugin that needs access to the metadata writes a custom Integrator, it would be nice if the Metadata was exposed centrally.

ref.:

a first implementation draft for further discussion will follow up as pull-request shortly.

Unique Constraint/Primary Key Validation issue

Steps to Reproduce

  1. Clone repo
  2. Run integration tests

Expected Behaviour

There should be a validation error (not unique).

Actual Behaviour

On calling save or insert exception: A different object with the same identifier value was already associated with the session org.springframework.dao.DuplicateKeyException
On calling validate returns true, even though unique constraint is violated.

Environment Information

  • Operating System: Windows
  • Grails Version: 3.2.9
  • JDK Version: 1.8

Example Application

https://github.com/KerchumA222/UniqueFailure
There are integration tests that express intended behavior.

hibernate-5.2 - NoSuchMethodError: org.hibernate.proxy.pojo.BasicLazyInitializer.<init>

BasicLazyInitializer constructor changed:
https://github.com/hibernate/hibernate-orm/blob/5.1.5/hibernate-core/src/main/java/org/hibernate/proxy/pojo/BasicLazyInitializer.java#L42
vs.
https://github.com/hibernate/hibernate-orm/blob/5.2.9/hibernate-core/src/main/java/org/hibernate/proxy/pojo/BasicLazyInitializer.java#L42

which results in a NoSuchMethodError with hibernate-5.2.x here:
https://github.com/grails/gorm-hibernate5/blob/v6.1.1/grails-datastore-gorm-hibernate5/src/main/groovy/org/grails/orm/hibernate/proxy/GroovyAwareJavassistLazyInitializer.java#L79

did not find any workaround, blocks upgrade to hibernate-5.2.

stacktrace:

java.lang.NoSuchMethodError: org.hibernate.proxy.pojo.BasicLazyInitializer.<init>(Ljava/lang/String;Ljava/lang/Class;Ljava/io/Serializable;Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;Lorg/hibernate/type/CompositeType;Lorg/hibernate/engine/spi/SessionImplementor;Z)V
	at org.grails.orm.hibernate.proxy.GroovyAwareJavassistLazyInitializer.<init>(GroovyAwareJavassistLazyInitializer.java:79)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at org.springsource.loaded.ri.ReflectiveInterceptor.jlrConstructorNewInstance(ReflectiveInterceptor.java:1075)
	at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:83)
	at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrapNoCoerce.callConstructor(ConstructorSite.java:105)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:60)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:235)
	at org.grails.orm.hibernate.proxy.ProxyFactorySupport.createProxy(ProxyFactorySupport.groovy:80)

thanks, zyro

Odd GORM transaction behavior after upgrading from Grails 2.5 to Grails 3.3.1

Some code that was working in 2.5.x is currently not working in 3.3.1. This particular issue is related to GORM and transactions participation (we think). Basically, I have two domain classes where 1 of them (Pipeline) has many of the other (Rule). I have two controllers where I can save a Pipeline first. Then, I call the RuleController to save a rule and add to the pipeline in a Service. However, I want to do some queries to find the Rule after I added it to the pipeline. (Notice this is a simplified example of querying for the Rule on other Pipelines.) However, I noticed that using CreateCriteria, ExecuteQuery, Where, will not get any data unless I flush the save of the pipeline. Is this the right behavior? We used to do this in Grails 2.5.x and it was yielding the data w/o flushing the save.

We are using mySQL as the persistent storage...

Here is the code to replicate the issue

Domain Class
Rule

class Rule {
    String name
    static constraints = {
    }
}

Pipeline

class Pipeline {
    String name
    static hasMany = [rules: Rule]
    static constraints = {
    }
}

Controllers
PipelineController

@Artefact("Controller")
class PipelineController extends RestfulController{
    static responseFormats = ['json', 'xml']
    PipelineController(){
        super(Pipeline)
    }
}

RuleController

@Artefact("Controller")
class RuleController extends RestfulController{
    static responseFormats = ['json', 'xml']
    def pipelineService

    RuleController(){
        super(Rule)
    }

    @Override
    def save() {
        def apiParams = request.SON
        def instance = pipelineService.addToPipeline(apiParams)
        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.created.message', args: [classMessageArg, instance.id])
                redirect instance
            }
            '*' {
                response.addHeader(HttpHeaders.LOCATION,
                        grailsLinkGenerator.link( resource: this.controllerName, action: 'show',id: instance.id, absolute: true,
                                namespace: hasProperty('namespace') ? this.namespace : null ))
                respond instance, [status: CREATED, view:'show']
            }
        }
    }
}

Service
PipelineService

@Transactional
class PipelineService {
    def addToPipeline(params) {
        def rule = new Rule(name: params.name)
        rule.save()
        def ruleID = rule.id
        Pipeline pipeline = Pipeline.get(params.pipelineId)
        pipeline.addToRules(rule)

        // commenting out save is the same as explicit save()
        pipeline.save()     // this will not allow createCriteria, where, or executeQuery to find pipeline for the just inserted rule
        //pipeline.save(flush:true)     // this will let all queries work

        // this gets the result no matter if we flush or not
        def results = Pipeline.list().findAll{rule in it.rules}

        // None of the queries below find anything unless save is flushed
        //

        // withTransactions or withSession still won't find unless flush is set
        //Pipeline.withTransaction{
        def c = Pipeline.createCriteria()
        def results2 = c.list {
            rules{
                eq("id",ruleID)
            }
        }
        //}

        def query = "select distinct p from Pipeline p inner join p.rules rules where rules in (:rule) "
        def results3 = []
        try{
            results3 = Pipeline.executeQuery(query,[rule:rule])
        }catch(e){
            e.printStackTrace()
        }

        def results4 = Pipeline.where {
            rules.id == ruleID
        }.list()

        println "results: ${results}"
        println "results2: ${results2}"
        println "results3: ${results3}"
        println "results3: ${results4}"

        return rule
    }
}

UrlMappings

        "/api/rules"(resources:'Rule')
        "/api/pipelines"(resources:'Pipeline')

Steps to reproduce:

  1. Create a new pipeline by POSTing to /api/pipelines
{"name":"Pipeline1"}
  1. Create a new rule to add to the newly created pipeline (ID 1) by POSTing to /api/rules
{"name":"rule1", "pipelineId":1} 
  1. The console should show the pipeline for all results but it is not finding them except for 1 of the queries. If we flush the save for the pipeline, then all queries will find the record in question. See comments in the Service class.

NamingStrategy is deprecated

In the docs to change hibernate naming strategy, we need to specify a class that must implement org.hibernate.cfg.NamingStrategy , which is deprecated. So what is the right way to do this? Will it be changed soon?

Something Wrong with gorm-hibernate5-spring-boot : 6.0.0.RELEASE

Hi,

Eh, I followed the docs and the example ( spring-boot-hibernate5 ) to build a simple spring-boot project with gorm, and I add a dependency in the pom.xml :

<dependency>
    <groupId>org.grails</groupId>
    <artifactId>gorm-hibernate5-spring-boot</artifactId>
    <version>6.0.0.RELEASE</version>
</dependency>

But, I found it didn't attach some necessary jars to the project. For example, it didn't find the class : grails.persistence.Entity, and I have to add a dependency: grails-datastore-gorm. In the end, I found there are such many jars I have to add to pom.xml by myself.

Finally, I changed 6.0.0.RELEASE to 6.0.0.RC2, and it worked !

I'm Grails honest fan, and I love gorm very much, it's powerful, so I hope you can provider a better gorm release version.

HibernateSpec is not using dataSource configuration

HibernateSpec setupSpec() is already doing all the work to load configuration (i.e., from application.yml and.or application.groovy), but it's not using the dataSource configuration when it instantiates HibernateDatastore at the end of setupSpec. It calls getConfiguration(), which all this does is set
SETTING_DB_CREATE to "create-drop" and leaves everything else unset, which causes Grails to use assumed defaults for the dataStore.

We (UC Berkeley, customer of OCI) have custom H2 database data types that we use in the INIT string for the dataSource url. Since HibernateSpec isn't using that url for the HibernateDatastore, our INIT string is ignored.

Can getConfigurations() be modified to use config.dataSource? Or perhaps, introduce a new config option that makes this behavior configurable for HibernateSpec? (I.e., a config option that tells HibernateSpec to use application.yml/application.groovy for dataSource configuration, which could be turned off by default to preserve existing behavior.)

CC @sbglasius

Slowness of joining domain class vs. raw SQL query

I'm having an interesting performance issue at work where a GORM query takes orders of magnitude to complete than a plain SQL. A mapping table represented by a composite primary key domain class (without any hasMany or belongsTo relations) takes 2 seconds to load via GORM while groovy.sql.Sql takes around 50ms. The actual queries are practically identical in both cases (verified with the SQL logger), so no N+1 selects problem.

My main question is whether this difference

  • is simply to be expected
  • is caused by us because we're doing something suboptimal
  • is a bug

I've simplified the case in a test app which I will upload somewhere (Github can't handle attachments apparently), but the gist of it is:

class Author implements DomainClass {
    Long id
    String name
}
class Book implements DomainClass {
    Long id
    String title
}
class BookAuthor implements DomainClass, Serializable{
    Book book
    Author author

	static mapping = {
		id composite:['book', 'author']
		version false
	}

	@Override
	boolean equals(other) {
		if (other instanceof BookAuthor) {
			other.author == author?.id && other.book == book?.id
		}
	}

    @Override
	int hashCode() {
		def builder = new HashCodeBuilder()
		if (author) builder.append(author.id)
		if (book) builder.append(book.id)
		builder.toHashCode()
	}
}
def index() {
        def authors = Author.findAll().groupBy { it.id }
        def books = Book.findAll().groupBy { it.id }


        long time = System.nanoTime();

        assert BookAuthor.findAll().size() == 7000
        long domainsLoadedAt = System.nanoTime()
        long timeOfDomainClassLoad = domainsLoadedAt - time;

        int itemsLoaded = 0
        new Sql(dataSource).eachRow("select author_id, book_id from book_author") { row ->
            assert authors.get(row.author_id)
            assert books.get(row.book_id)
            itemsLoaded++
        }
        assert itemsLoaded == 7000
        long timeOfPlainQuery = System.nanoTime() - domainsLoadedAt;

        render text: "Loaded BookAuthor domains in ${timeOfDomainClassLoad / 1000000.0}ms while query took ${timeOfPlainQuery / 1000000.0}ms"

    }

I also have a Bootstrap class that creates 500 Authors, 1500 Books and 7000 BookAuthors (this roughly matches the amounts of data we have in the real application).

Under Hibernate 4 the typical response is Loaded BookAuthor domains in 1325.219786ms while query took 70.200815ms while Hibernate 5 is giving me Loaded BookAuthor domains in 844.710136ms while query took 20.408714ms. We're using Postgres, not the in-mem database in reality, but it should not matter and the results look similar on both.

Setting schema per datasource not possible

Grails 3.2.8
Gorm 6.0.9 & 6.1.1
Gradle 2.9
Java 1.8

Having multiple datasources with different schemes it is not possible to set a default_schema for each datasource.

plugin.groovy or application.groovy:
hibernate { default_schema = "schema1" } hibernate_second { default_schema = "schema2" }

when using a domain from the second datasource you get: "schema1 does not exist"

Multi-tenancy not working with inheritance

Scenario

Grails 3.1.10
gorm 6.0.0
jdk 1.8

Multitenant application with 3 tenants

  1. default (masterdata)
  2. test-one
  3. test-two

Classes with nature of inheritance

  1. user (abstract base class) (tenant 2,3)
  2. person (child of user) (tenant 2,3)
  3. institute (child of user) (tenant 2,3)
  4. employee (child of person) (tenant 2,3)
  5. superEmployee (child of employee) (tenant 3)

Issues

I found two issues.

  1. I defined datasources mapping properties for the multi-tenant classes. datasources (['test-one','test-two']) defined.
    Expected : Tables created only under test-one and test-two.
    Actual : tables created under dataScource, teat-one and test-two

  2. Child class superEmployee is not defined as multi-tenant. datasource 'test-two' defined.
    Expected : table created only under tenant test-two
    actual : table created under all tenants

Please find test application attached for your reference.

test1.zip

Changing name of association column name

In app I am working on we already have tables where columns are named in camel case (for example "userId"). And dont want to add column name in mapping for each association in domain.
Currently, default behavior for naming columns for associations is just to add "_id" which is set here
So is it possible to make FOREIGN_KEY_SUFFIX configurable, that will be great, or at least not final protected so it can be changed?

Table created in incorrect database

The following domains result in all domains being created in both the humans and dogs databases, even though the Human domain specifies a single datasource (humans) and the Dog domain specifies a single datasource (dogs):

class Mammal {
    String scientificName

    static mapping = {
        tablePerHierarchy false
        datasources(['dogs', 'humans'])
    }
}

class Human extends Mammal {
    String name

    static mapping = {
        datasource "humans"
    }
}

class Dog extends Mammal {
    String breed
    String name

    static mapping = {
        datasource "dogs"
    }
}

Hibernate's legacy org.hibernate.Criteria API is deprecated

I don't know if this belongs here or in the grails-data-mapping/grails-datastore-gorm-hibernate-core but these are WARN level messages, which we can disable using logback but the codebase should probably be updated.

The full message is:
HHH90000022: Hibernate's legacy org.hibernate.Criteria API is deprecated; use the JPA javax.persistence.criteria.CriteriaQuery instead

Using springboot controller to Automatic loading Domain class, the domain class couldn't update data?

I post my form to springboot controller action , want to update data. code like this:

    @RequestMapping(value = "update")
    @ResponseBody
    public Map update(Book bookInstance,javax.servlet.http.HttpServletRequest request,Model model){
        if (bookInstance.hasErrors()) {
            foundErrors(bookInstance);
            return [result:false]
        }
        def result=bookInstance.save(flush: true)
        println "result=${result}"
        println bookInstance.errors
        if (!result) {
            foundErrors(bookInstance);
            return [result:false]
        }else{
            return [result:true]
        }
    }

bookInstance.save(flush: true)

couldn't update data.
i add

logSql: true

in application.yml, the output sql like this , lack update sql:

Hibernate: select count(*) as y0_ from book this_
Hibernate: select this_.id as id1_5_0_, this_.version as version2_5_0_, this_.title as title3_5_0_, this_.PRICE_COLUMN as PRICE_CO4_5_0_, this_.publish_date as publish_5_5_0_, this_.author_id as author_i6_5_0_ from book this_ order by this_.id desc limit ?
Hibernate: select this_.id as id1_1_0_, this_.version as version2_1_0_, this_.name as name3_1_0_, this_.birthday as birthday4_1_0_ from author this_ where this_.id = ?

but the save code could work fine in save action,the only difference is update form add tow hidden field

    <input type="hidden" name="id" id="id" th:value="${bookInstance.id}"/>
    <input type="hidden" name="version" id="version" th:value="${bookInstance.version}"/>

using generate-all command in grails3.2.8, get this code:

    @Transactional
    def update(Book book) {
        if (book == null) {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }
        if (book.hasErrors()) {
            transactionStatus.setRollbackOnly()
            respond book.errors, view:'edit'
            return
        }
        book.save flush:true
        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.updated.message', args: [message(code: 'book.label', default: 'Book'), book.id])
                redirect book
            }
            '*'{ respond book, [status: OK] }
        }
    }

it's ok under grails3.2.8 , what's the different mechanism to auto load between grails controller and springboot controller ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.