HHH-14460 Validate setter exists for persistent property also with mixed access strategy

This commit is contained in:
Christian Beikov 2021-02-16 15:11:43 +01:00
parent 0b951ef803
commit 91a68c6746
2 changed files with 94 additions and 2 deletions

View File

@ -25,7 +25,7 @@ import org.hibernate.property.access.spi.SetterFieldImpl;
import org.hibernate.property.access.spi.SetterMethodImpl; import org.hibernate.property.access.spi.SetterMethodImpl;
import static org.hibernate.internal.util.ReflectHelper.getterMethodOrNull; import static org.hibernate.internal.util.ReflectHelper.getterMethodOrNull;
import static org.hibernate.internal.util.ReflectHelper.setterMethodOrNull; import static org.hibernate.internal.util.ReflectHelper.findSetterMethod;
/** /**
* A PropertyAccess based on mix of getter/setter method and/or field. * A PropertyAccess based on mix of getter/setter method and/or field.
@ -65,7 +65,7 @@ public class PropertyAccessMixedImpl implements PropertyAccess {
"Could not locate getter for property named [" + containerJavaType.getName() + "#" + propertyName + "]" "Could not locate getter for property named [" + containerJavaType.getName() + "#" + propertyName + "]"
); );
} }
Method setterMethod = setterMethodOrNull( containerJavaType, propertyName, getterMethod.getReturnType() ); Method setterMethod = findSetterMethod( containerJavaType, propertyName, getterMethod.getReturnType() );
this.getter = propertyGetter( containerJavaType, propertyName, getterMethod ); this.getter = propertyGetter( containerJavaType, propertyName, getterMethod );
this.setter = propertySetter( containerJavaType, propertyName, setterMethod ); this.setter = propertySetter( containerJavaType, propertyName, setterMethod );

View File

@ -0,0 +1,92 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.test.proxy;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.hibernate.MappingException;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.testing.ServiceRegistryBuilder;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
/**
*
* @author Christian Beikov
*/
@TestForIssue(jiraKey = "HHH-14460")
@RunWith( BytecodeEnhancerRunner.class )
public class MissingSetterWithEnhancementTest {
private ServiceRegistry serviceRegistry;
@Before
public void setUp() {
final BootstrapServiceRegistryBuilder builder = new BootstrapServiceRegistryBuilder();
builder.applyClassLoader( getClass().getClassLoader() );
serviceRegistry = new StandardServiceRegistryBuilder( builder.build() )
.applySettings( Environment.getProperties() )
.build();
}
@After
public void tearDown() {
if ( serviceRegistry != null ) {
ServiceRegistryBuilder.destroy( serviceRegistry );
}
}
@Test
public void testEnhancedClassMissesSetterForProperty() {
Configuration cfg = new Configuration();
cfg.addAnnotatedClass( EntityWithMissingSetter.class );
try (SessionFactory sf = cfg.buildSessionFactory( serviceRegistry )) {
fail( "Setter is missing for `name`. SessionFactory creation should fail." );
}
catch (MappingException e) {
assertEquals(
"Could not locate setter method for property [" + EntityWithMissingSetter.class.getName() + "#name]",
e.getCause().getCause().getCause().getMessage()
);
}
}
@Entity
public static class EntityWithMissingSetter {
private Long id;
@Column
private int someInt;
@Id
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return null;
}
}
}