diff --git a/modules/core/src/com/haulmont/cuba/core/sys/EntityManagerImpl.java b/modules/core/src/com/haulmont/cuba/core/sys/EntityManagerImpl.java index 1a2e1211a9..1c91fef60f 100644 --- a/modules/core/src/com/haulmont/cuba/core/sys/EntityManagerImpl.java +++ b/modules/core/src/com/haulmont/cuba/core/sys/EntityManagerImpl.java @@ -443,7 +443,7 @@ public class EntityManagerImpl implements EntityManager { for (MetaProperty property : metadata.getClassNN(entity.getClass()).getProperties()) { if (metadata.getTools().isNotPersistent(property) && !property.isReadOnly()) { // copy using reflection to avoid executing getter/setter code - Field field = FieldUtils.getDeclaredField(entity.getClass(), property.getName(), true); + Field field = FieldUtils.getField(entity.getClass(), property.getName(), true); if (field != null) { try { Object value = FieldUtils.readField(field, entity); diff --git a/modules/core/test/com/haulmont/cuba/testmodel/not_persistent/BaseEntityWithNonPersistentProperty.java b/modules/core/test/com/haulmont/cuba/testmodel/not_persistent/BaseEntityWithNonPersistentProperty.java new file mode 100644 index 0000000000..87074fc553 --- /dev/null +++ b/modules/core/test/com/haulmont/cuba/testmodel/not_persistent/BaseEntityWithNonPersistentProperty.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2008-2018 Haulmont. + * + * Licensed 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 + * + * http://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 com.haulmont.cuba.testmodel.not_persistent; + +import com.haulmont.chile.core.annotations.MetaProperty; +import com.haulmont.cuba.core.entity.StandardEntity; + +import javax.persistence.MappedSuperclass; +import javax.persistence.Transient; + +@MappedSuperclass +public class BaseEntityWithNonPersistentProperty extends StandardEntity { + + @Transient + @MetaProperty + protected String reason; + + public String getReason() { + return reason; + } + + public void setReason(String reason) { + this.reason = reason; + } +} diff --git a/modules/core/test/com/haulmont/cuba/testmodel/not_persistent/CustomerWithNonPersistentRef.java b/modules/core/test/com/haulmont/cuba/testmodel/not_persistent/CustomerWithNonPersistentRef.java index 82ea2c86ee..e7641924d3 100644 --- a/modules/core/test/com/haulmont/cuba/testmodel/not_persistent/CustomerWithNonPersistentRef.java +++ b/modules/core/test/com/haulmont/cuba/testmodel/not_persistent/CustomerWithNonPersistentRef.java @@ -18,17 +18,14 @@ package com.haulmont.cuba.testmodel.not_persistent; import com.haulmont.chile.core.annotations.MetaProperty; import com.haulmont.chile.core.annotations.NamePattern; -import com.haulmont.chile.core.datatypes.impl.EnumUtils; -import com.haulmont.cuba.core.entity.StandardEntity; import com.haulmont.cuba.testmodel.primary_keys.EntityKey; -import com.haulmont.cuba.testmodel.sales.Status; import javax.persistence.*; @Entity(name = "test$CustomerWithNonPersistentRef") @Table(name = "TEST_CUSTOMER_W_NPERS_REF") @NamePattern("%s|name") -public class CustomerWithNonPersistentRef extends StandardEntity { +public class CustomerWithNonPersistentRef extends BaseEntityWithNonPersistentProperty { @Column(name = "NAME") private String name; diff --git a/modules/core/test/cuba-test-persistence.xml b/modules/core/test/cuba-test-persistence.xml index aa4969c572..c1ba54a72d 100644 --- a/modules/core/test/cuba-test-persistence.xml +++ b/modules/core/test/cuba-test-persistence.xml @@ -95,6 +95,7 @@ com.haulmont.cuba.testmodel.jpa_cascade.JpaCascadeBar com.haulmont.cuba.testmodel.jpa_cascade.JpaCascadeItem + com.haulmont.cuba.testmodel.not_persistent.BaseEntityWithNonPersistentProperty com.haulmont.cuba.testmodel.not_persistent.CustomerWithNonPersistentRef com.haulmont.cuba.testmodel.localdatetime.LocalDateTimeEntity diff --git a/modules/core/test/spec/cuba/core/entity_manager/EntityManagerTest.groovy b/modules/core/test/spec/cuba/core/entity_manager/EntityManagerTest.groovy new file mode 100644 index 0000000000..9937a2974b --- /dev/null +++ b/modules/core/test/spec/cuba/core/entity_manager/EntityManagerTest.groovy @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2008-2018 Haulmont. + * + * Licensed 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 + * + * http://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 spec.cuba.core.entity_manager + +import com.haulmont.cuba.core.global.AppBeans +import com.haulmont.cuba.core.global.DataManager +import com.haulmont.cuba.testmodel.not_persistent.CustomerWithNonPersistentRef +import com.haulmont.cuba.testmodel.not_persistent.TestNotPersistentEntity +import com.haulmont.cuba.testmodel.primary_keys.EntityKey +import com.haulmont.cuba.testsupport.TestContainer +import org.junit.ClassRule +import spock.lang.Shared +import spock.lang.Specification + +class EntityManagerTest extends Specification { + + @Shared @ClassRule + public TestContainer cont = TestContainer.Common.INSTANCE + + private DataManager dataManager + + void setup() { + dataManager = AppBeans.get(DataManager) + } + + def "non-persistent property from superclass is copied back after merge #1150"() { + + EntityKey entityKey = new EntityKey(tenant: 1, entityId: 10) + TestNotPersistentEntity notPersistentEntity = new TestNotPersistentEntity(name: 'entity1', info: 'something') + CustomerWithNonPersistentRef customer = new CustomerWithNonPersistentRef(reason: 'some reason', name: 'cust1', entityKey: entityKey, notPersistentEntity: notPersistentEntity) + + when: + + CustomerWithNonPersistentRef customer1 = dataManager.commit(customer) + + then: + + customer1.name == 'cust1' + customer1.entityKey.tenant == 1 + customer1.entityKey.entityId == 10 + customer1.notPersistentEntity.name == 'entity1' + customer1.notPersistentEntity.info == 'something' + customer1.reason == 'some reason' + + when: + + customer1.name = 'cust11' + customer1.reason = 'reason11' + CustomerWithNonPersistentRef customer2 = dataManager.commit(customer1) + + then: + + customer2.name == 'cust11' + customer2.entityKey.tenant == 1 + customer2.entityKey.entityId == 10 + customer2.notPersistentEntity.name == 'entity1' + customer2.notPersistentEntity.info == 'something' + customer2.reason == 'reason11' + + cleanup: + + cont.deleteRecord(customer) + } +}