borinquenkid commented on code in PR #15568:
URL: https://github.com/apache/grails-core/pull/15568#discussion_r3462897760


##########
grails-data-hibernate5/core/src/test/groovy/grails/gorm/tests/IdentityEnumTypeSpec.groovy:
##########
@@ -20,52 +20,209 @@ package grails.gorm.tests
 
 import grails.gorm.annotation.Entity
 import grails.gorm.transactions.Rollback
-import org.grails.orm.hibernate.HibernateDatastore
-import org.springframework.transaction.PlatformTransactionManager
-import spock.lang.AutoCleanup
-import spock.lang.Shared
-import spock.lang.Specification
+import jakarta.persistence.Enumerated
+import jakarta.persistence.EnumType
+import org.grails.orm.hibernate.cfg.IdentityEnumType
+import org.hibernate.HibernateException
+import org.hibernate.MappingException
+import org.hibernate.engine.spi.SharedSessionContractImplementor
 
 import javax.sql.DataSource
 import java.sql.ResultSet
 
 /**
- * Created by graemerocher on 16/11/16.
+ * Tests for IdentityEnumType in Hibernate 5.
  */
-class IdentityEnumTypeSpec extends Specification {
+class IdentityEnumTypeSpec extends HibernateGormDatastoreSpec {
 
-    @Shared @AutoCleanup HibernateDatastore hibernateDatastore = new 
HibernateDatastore(EnumEntityDomain, FooWithEnum)
-    @Shared PlatformTransactionManager transactionManager = 
hibernateDatastore.getTransactionManager()
+    def setupSpec() {
+        manager.registerDomainClasses(EnumEntityDomain, FooWithEnum)
+    }
 
     @Rollback
     void "test identity enum type"() {
         when:
-        new EnumEntityDomain(status: 
EnumEntityDomain.Status.FOO).save(flush:true)
-        DataSource ds = 
hibernateDatastore.connectionSources.defaultConnectionSource.dataSource
+        new EnumEntityDomain(status: EnumEntityDomain.Status.FOO).save(flush: 
true)
+        DataSource ds = 
manager.hibernateDatastore.connectionSources.defaultConnectionSource.dataSource
         ResultSet resultSet = ds.getConnection().prepareStatement('select 
status from enum_entity_domain').executeQuery()
 
         then:
         resultSet.next()
-        resultSet.getString(1) == 'F'
+        resultSet.getString(1) == 'F' // FOO id is 'F'
         EnumEntityDomain.first().status == EnumEntityDomain.Status.FOO
     }
 
     @Rollback
     void "test identity enum type 2"() {
         when:
-        new FooWithEnum(name: "blah", mySuperValue: 
XEnum.X__TWO).save(flush:true)
-        DataSource ds = 
hibernateDatastore.connectionSources.defaultConnectionSource.dataSource
+        new FooWithEnum(name: "blah", mySuperValue: XEnum.X__TWO).save(flush: 
true)
+        DataSource ds = 
manager.hibernateDatastore.connectionSources.defaultConnectionSource.dataSource
         ResultSet resultSet = ds.getConnection().prepareStatement('select 
my_super_value from foo_with_enum').executeQuery()
 
         then:
         resultSet.next()
-        resultSet.getInt(1) == 100
+        resultSet.getInt(1) == 100 // X__TWO id is 100
         FooWithEnum.first().mySuperValue == XEnum.X__TWO
     }
+
+    def "setParameterValues initializes enumClass"() {
+        given:
+        def type = new IdentityEnumType()
+        def props = new Properties()
+        props.setProperty(IdentityEnumType.PARAM_ENUM_CLASS, 
IdentityStatusEnum.name)
+
+        when:
+        type.setParameterValues(props)
+
+        then:
+        type.returnedClass() == IdentityStatusEnum
+        type.sqlTypes()[0] != 0
+    }
+
+    def "setParameterValues throws MappingException for enum without getId 
method"() {
+        given:
+        def type = new IdentityEnumType()
+        def props = new Properties()
+        props.setProperty(IdentityEnumType.PARAM_ENUM_CLASS, PlainEnum.name)
+
+        when:
+        type.setParameterValues(props)
+
+        then:
+        thrown(HibernateException) // Throw by BidiEnumMap constructor
+    }
+
+    def "equals uses identity comparison"() {
+        given:
+        def type = new IdentityEnumType()
+
+        expect:
+        type.equals(IdentityStatusEnum.ACTIVE, IdentityStatusEnum.ACTIVE)
+        !type.equals(IdentityStatusEnum.ACTIVE, IdentityStatusEnum.INACTIVE)
+        !type.equals(null, IdentityStatusEnum.ACTIVE)
+    }
+
+    def "hashCode delegates to the object"() {
+        given:
+        def type = new IdentityEnumType()
+        def val = IdentityStatusEnum.ACTIVE
+
+        expect:
+        type.hashCode(val) == val.hashCode()
+    }
+
+    def "deepCopy returns the same object reference"() {
+        given:
+        def type = new IdentityEnumType()
+        def val = IdentityStatusEnum.ACTIVE
+
+        expect:
+        type.deepCopy(val).is(val)
+    }
+
+    def "isMutable returns false"() {
+        expect:
+        !new IdentityEnumType().isMutable()
+    }
+
+    def "disassemble returns the value as Serializable"() {
+        given:
+        def type = new IdentityEnumType()
+        def val = IdentityStatusEnum.ACTIVE
+
+        expect:
+        type.disassemble(val).is(val)
+    }
+
+    def "assemble returns the cached value unchanged"() {
+        given:
+        def type = new IdentityEnumType()
+        def val = IdentityStatusEnum.ACTIVE
+
+        expect:
+        type.assemble(val, null).is(val)
+    }
+
+    def "replace returns the original value"() {
+        given:
+        def type = new IdentityEnumType()
+
+        expect:
+        type.replace(IdentityStatusEnum.ACTIVE, IdentityStatusEnum.INACTIVE, 
null).is(IdentityStatusEnum.ACTIVE)
+    }
+
+    def "nullSafeGet returns null for null value"() {
+        given:
+        def type = new IdentityEnumType()
+        def props = new Properties()
+        props.setProperty(IdentityEnumType.PARAM_ENUM_CLASS, 
IdentityStatusEnum.name)
+        type.setParameterValues(props)
+        def rs = Mock(java.sql.ResultSet)
+        def session = manager.sessionFactory.currentSession as 
SharedSessionContractImplementor
+
+        when:
+        def res = type.nullSafeGet(rs, ['status'] as String[], session, null)
+
+        then:
+        1 * rs.getString('status') >> null
+        1 * rs.wasNull() >> true
+        res == null
+    }
+
+    def "nullSafeGet converts id to enum"() {
+        given:
+        def type = new IdentityEnumType()
+        def props = new Properties()
+        props.setProperty(IdentityEnumType.PARAM_ENUM_CLASS, 
IdentityStatusEnum.name)
+        type.setParameterValues(props)
+        def rs = Mock(java.sql.ResultSet)
+        def session = manager.sessionFactory.currentSession as 
SharedSessionContractImplementor
+
+        when:
+        def res = type.nullSafeGet(rs, ['status'] as String[], session, null)
+
+        then:
+        1 * rs.getString('status') >> "A"
+        2 * rs.wasNull() >> false
+        res == IdentityStatusEnum.ACTIVE
+    }
+
+    def "nullSafeSet handles null value"() {
+        given:
+        def type = new IdentityEnumType()
+        def props = new Properties()
+        props.setProperty(IdentityEnumType.PARAM_ENUM_CLASS, 
IdentityStatusEnum.name)
+        type.setParameterValues(props)
+        def st = Mock(java.sql.PreparedStatement)
+        def session = manager.sessionFactory.currentSession as 
SharedSessionContractImplementor
+
+        when:
+        type.nullSafeSet(st, null, 1, session)
+
+        then:
+        1 * st.setNull(1, _)
+    }
+
+    def "nullSafeSet converts enum to id"() {
+        given:
+        def type = new IdentityEnumType()
+        def props = new Properties()
+        props.setProperty(IdentityEnumType.PARAM_ENUM_CLASS, 
IdentityStatusEnum.name)
+        type.setParameterValues(props)
+        def st = Mock(java.sql.PreparedStatement)
+        def session = manager.sessionFactory.currentSession as 
SharedSessionContractImplementor
+
+        when:
+        type.nullSafeSet(st, IdentityStatusEnum.INACTIVE, 1, session)
+
+        then:
+        1 * st.setString(1, "I")
+    }
 }
 
 @Entity
 class EnumEntityDomain {
+    @Enumerated(EnumType.STRING)

Review Comment:
   Confirmed — you were right. The `@Enumerated(EnumType.STRING)` was added by 
mistake during a merge and contradicts the `enumType: identity` mapping: the 
custom `IdentityEnumType` stores the enum id field, not the name, so the JPA 
annotation is ignored regardless. Removed from both fields in commit 
`6bc90ca6f7`. Resolving.



##########
grails-data-hibernate5/core/src/test/groovy/grails/gorm/tests/IdentityEnumTypeSpec.groovy:
##########
@@ -83,18 +240,19 @@ class EnumEntityDomain {
 class FooWithEnum {
     long id
     String name
+    @Enumerated(EnumType.STRING)

Review Comment:
   Same as the field above — `@Enumerated` removed in commit `6bc90ca6f7`. 
Resolving.



##########
grails-data-hibernate5/core/src/test/groovy/org/grails/datastore/mapping/model/PersistentPropertySpec.groovy:
##########
@@ -0,0 +1,92 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    https://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.grails.datastore.mapping.model
+
+import grails.gorm.tests.HibernateGormDatastoreSpec
+import grails.persistence.Entity
+import spock.lang.Issue
+
+@Issue('https://github.com/grails/grails-data-mapping/issues/1299')

Review Comment:
   You were right to question it. The `@Issue` pointed at 
grails-data-mapping#1299, which is about MongoDB config builder recursion and 
unrelated to this spec — it was copied over when the spec was ported between 
modules. Removed from both H5 and H7. Resolving.



##########
grails-data-hibernate5/core/src/test/groovy/org/grails/orm/hibernate/HibernateDatastoreMultiTenancySpec.groovy:
##########
@@ -0,0 +1,101 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    https://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.grails.orm.hibernate
+
+import grails.gorm.MultiTenant
+import grails.gorm.annotation.Entity
+import grails.gorm.multitenancy.Tenants
+import grails.gorm.tests.HibernateGormDatastoreSpec
+import org.grails.datastore.mapping.core.connections.ConnectionSource
+import org.grails.datastore.mapping.multitenancy.MultiTenancySettings
+import 
org.grails.datastore.mapping.multitenancy.resolvers.SystemPropertyTenantResolver
+import org.grails.orm.hibernate.cfg.Settings
+import org.hibernate.FlushMode
+import spock.lang.Issue
+
+import javax.sql.DataSource
+

Review Comment:
   Confirmed — the unused `grails.gorm.multitenancy.Tenants` import is removed. 
Resolving.



##########
grails-data-hibernate5/core/src/test/groovy/org/grails/orm/hibernate/proxy/HibernateProxyHandler5Spec.groovy:
##########
@@ -0,0 +1,325 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    https://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.grails.orm.hibernate.proxy
+
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+import grails.gorm.tests.HibernateGormDatastoreSpec
+import org.apache.grails.data.hibernate5.core.GrailsDataHibernate5TckManager
+import org.apache.grails.data.testing.tck.base.GrailsDataTckSpec
+import org.apache.grails.data.testing.tck.domains.Location
+import org.apache.grails.data.testing.tck.domains.Person
+import org.apache.grails.data.testing.tck.domains.Pet
+import org.hibernate.Hibernate
+import spock.lang.Shared
+import org.grails.datastore.gorm.proxy.GroovyProxyFactory
+
+class HibernateProxyHandler5Spec extends  
GrailsDataTckSpec<GrailsDataHibernate5TckManager> {

Review Comment:
   A straight answer, since the earlier replies were muddled: it does not 
extend `HibernateGormDatastoreSpec` (that is the H7 base). It extends 
`GrailsDataTckSpec<GrailsDataHibernate5TckManager>`, the H5 TCK base class, 
which is the correct H5 analog. Resolving.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to