HHH-12749 - Avoid setting the isolation level to the same value in C3P0ConnectionProvider
This commit is contained in:
parent
3a3b0740df
commit
6146809af2
|
@ -9,6 +9,8 @@ dependencies {
|
||||||
compile( libraries.c3p0 )
|
compile( libraries.c3p0 )
|
||||||
|
|
||||||
testCompile project( ':hibernate-testing' )
|
testCompile project( ':hibernate-testing' )
|
||||||
|
testCompile( libraries.mockito )
|
||||||
|
testCompile( libraries.mockito_inline )
|
||||||
|
|
||||||
testCompile( libraries.validator ) {
|
testCompile( libraries.validator ) {
|
||||||
// for test runtime
|
// for test runtime
|
||||||
|
|
|
@ -71,7 +71,7 @@ public class C3P0ConnectionProvider
|
||||||
@SuppressWarnings("UnnecessaryUnboxing")
|
@SuppressWarnings("UnnecessaryUnboxing")
|
||||||
public Connection getConnection() throws SQLException {
|
public Connection getConnection() throws SQLException {
|
||||||
final Connection c = ds.getConnection();
|
final Connection c = ds.getConnection();
|
||||||
if ( isolation != null ) {
|
if ( isolation != null && !isolation.equals( c.getTransactionIsolation() ) ) {
|
||||||
c.setTransactionIsolation( isolation.intValue() );
|
c.setTransactionIsolation( isolation.intValue() );
|
||||||
}
|
}
|
||||||
if ( c.getAutoCommit() != autocommit ) {
|
if ( c.getAutoCommit() != autocommit ) {
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
package org.hibernate.test.c3p0;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
import org.hibernate.boot.SessionFactoryBuilder;
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.dialect.H2Dialect;
|
||||||
|
|
||||||
|
import org.hibernate.testing.RequiresDialect;
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
import org.hibernate.testing.jdbc.SQLStatementInterceptor;
|
||||||
|
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Vlad Mihalcea
|
||||||
|
*/
|
||||||
|
@TestForIssue(jiraKey = "HHH-12749")
|
||||||
|
@RequiresDialect(H2Dialect.class)
|
||||||
|
public class C3P0DefaultIsolationLevelTest extends
|
||||||
|
BaseNonConfigCoreFunctionalTestCase {
|
||||||
|
|
||||||
|
private C3P0ProxyConnectionProvider connectionProvider;
|
||||||
|
private SQLStatementInterceptor sqlStatementInterceptor;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configureSessionFactoryBuilder(SessionFactoryBuilder sfb) {
|
||||||
|
sqlStatementInterceptor = new SQLStatementInterceptor( sfb );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
|
return new Class<?>[] {
|
||||||
|
Person.class,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addSettings(Map settings) {
|
||||||
|
connectionProvider = new C3P0ProxyConnectionProvider();
|
||||||
|
settings.put( AvailableSettings.CONNECTION_PROVIDER, connectionProvider );
|
||||||
|
settings.put( AvailableSettings.ISOLATION, "READ_COMMITTED" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStoredProcedureOutParameter() throws SQLException {
|
||||||
|
clearSpies();
|
||||||
|
|
||||||
|
doInHibernate( this::sessionFactory, session -> {
|
||||||
|
Person person = new Person();
|
||||||
|
person.id = 1L;
|
||||||
|
person.name = "Vlad Mihalcea";
|
||||||
|
|
||||||
|
session.persist( person );
|
||||||
|
} );
|
||||||
|
|
||||||
|
assertEquals( 1, sqlStatementInterceptor.getSqlQueries().size() );
|
||||||
|
assertTrue( sqlStatementInterceptor.getSqlQueries().get( 0 ).toLowerCase().startsWith( "insert into" ) );
|
||||||
|
Connection connectionSpy = connectionProvider.getConnectionSpyMap().keySet().iterator().next();
|
||||||
|
verify( connectionSpy, never() ).setTransactionIsolation( Connection.TRANSACTION_READ_COMMITTED );
|
||||||
|
|
||||||
|
clearSpies();
|
||||||
|
|
||||||
|
doInHibernate( this::sessionFactory, session -> {
|
||||||
|
Person person = session.find( Person.class, 1L );
|
||||||
|
|
||||||
|
assertEquals( "Vlad Mihalcea", person.name );
|
||||||
|
} );
|
||||||
|
|
||||||
|
assertEquals( 1, sqlStatementInterceptor.getSqlQueries().size() );
|
||||||
|
assertTrue( sqlStatementInterceptor.getSqlQueries().get( 0 ).toLowerCase().startsWith( "select" ) );
|
||||||
|
connectionSpy = connectionProvider.getConnectionSpyMap().keySet().iterator().next();
|
||||||
|
verify( connectionSpy, never() ).setTransactionIsolation( Connection.TRANSACTION_READ_COMMITTED );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearSpies() {
|
||||||
|
sqlStatementInterceptor.getSqlQueries().clear();
|
||||||
|
connectionProvider.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "Person")
|
||||||
|
public static class Person {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
package org.hibernate.test.c3p0;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
import org.hibernate.boot.SessionFactoryBuilder;
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.dialect.H2Dialect;
|
||||||
|
|
||||||
|
import org.hibernate.testing.RequiresDialect;
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
import org.hibernate.testing.jdbc.SQLStatementInterceptor;
|
||||||
|
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Vlad Mihalcea
|
||||||
|
*/
|
||||||
|
@TestForIssue(jiraKey = "HHH-12749")
|
||||||
|
@RequiresDialect(H2Dialect.class)
|
||||||
|
public class C3P0DifferentIsolationLevelTest extends
|
||||||
|
BaseNonConfigCoreFunctionalTestCase {
|
||||||
|
|
||||||
|
private C3P0ProxyConnectionProvider connectionProvider;
|
||||||
|
private SQLStatementInterceptor sqlStatementInterceptor;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configureSessionFactoryBuilder(SessionFactoryBuilder sfb) {
|
||||||
|
sqlStatementInterceptor = new SQLStatementInterceptor( sfb );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
|
return new Class<?>[] {
|
||||||
|
Person.class,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addSettings(Map settings) {
|
||||||
|
connectionProvider = new C3P0ProxyConnectionProvider();
|
||||||
|
settings.put( AvailableSettings.CONNECTION_PROVIDER, connectionProvider );
|
||||||
|
settings.put( AvailableSettings.ISOLATION, "REPEATABLE_READ" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStoredProcedureOutParameter() throws SQLException {
|
||||||
|
clearSpies();
|
||||||
|
|
||||||
|
doInHibernate( this::sessionFactory, session -> {
|
||||||
|
Person person = new Person();
|
||||||
|
person.id = 1L;
|
||||||
|
person.name = "Vlad Mihalcea";
|
||||||
|
|
||||||
|
session.persist( person );
|
||||||
|
} );
|
||||||
|
|
||||||
|
assertEquals( 1, sqlStatementInterceptor.getSqlQueries().size() );
|
||||||
|
assertTrue( sqlStatementInterceptor.getSqlQueries().get( 0 ).toLowerCase().startsWith( "insert into" ) );
|
||||||
|
Connection connectionSpy = connectionProvider.getConnectionSpyMap().keySet().iterator().next();
|
||||||
|
verify( connectionSpy, times(1) ).setTransactionIsolation( Connection.TRANSACTION_REPEATABLE_READ );
|
||||||
|
|
||||||
|
clearSpies();
|
||||||
|
|
||||||
|
doInHibernate( this::sessionFactory, session -> {
|
||||||
|
Person person = session.find( Person.class, 1L );
|
||||||
|
|
||||||
|
assertEquals( "Vlad Mihalcea", person.name );
|
||||||
|
} );
|
||||||
|
|
||||||
|
assertEquals( 1, sqlStatementInterceptor.getSqlQueries().size() );
|
||||||
|
assertTrue( sqlStatementInterceptor.getSqlQueries().get( 0 ).toLowerCase().startsWith( "select" ) );
|
||||||
|
connectionSpy = connectionProvider.getConnectionSpyMap().keySet().iterator().next();
|
||||||
|
verify( connectionSpy, times(1) ).setTransactionIsolation( Connection.TRANSACTION_REPEATABLE_READ );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearSpies() {
|
||||||
|
sqlStatementInterceptor.getSqlQueries().clear();
|
||||||
|
connectionProvider.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "Person")
|
||||||
|
public static class Person {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
package org.hibernate.test.c3p0;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.hibernate.c3p0.internal.C3P0ConnectionProvider;
|
||||||
|
|
||||||
|
import org.hibernate.testing.util.ReflectionUtil;
|
||||||
|
|
||||||
|
import org.mockito.MockSettings;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Vlad Mihalcea
|
||||||
|
*/
|
||||||
|
public class C3P0ProxyConnectionProvider extends C3P0ConnectionProvider {
|
||||||
|
|
||||||
|
private static final MockSettings VERIFIEABLE_MOCK_SETTINGS = Mockito.withSettings()
|
||||||
|
.defaultAnswer( org.mockito.Answers.CALLS_REAL_METHODS );
|
||||||
|
|
||||||
|
private final Map<Connection, Connection> connectionSpyMap = new HashMap<>();
|
||||||
|
|
||||||
|
private static <T> T spy(T subject) {
|
||||||
|
return Mockito.mock( (Class<T>) subject.getClass(), VERIFIEABLE_MOCK_SETTINGS.spiedInstance( subject ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configure(Map props) {
|
||||||
|
super.configure( props );
|
||||||
|
DataSource ds = unwrap( DataSource.class );
|
||||||
|
DataSource dataSource = spy( ds );
|
||||||
|
|
||||||
|
try {
|
||||||
|
Mockito.doAnswer( invocation -> {
|
||||||
|
Connection connection = (Connection) invocation.callRealMethod();
|
||||||
|
Connection connectionSpy = spy( connection );
|
||||||
|
connectionSpyMap.put( connectionSpy, connection );
|
||||||
|
return connectionSpy;
|
||||||
|
} ).when( dataSource ).getConnection();
|
||||||
|
}
|
||||||
|
catch (SQLException e) {
|
||||||
|
throw new IllegalStateException( e );
|
||||||
|
}
|
||||||
|
|
||||||
|
ReflectionUtil.setField( C3P0ConnectionProvider.class.cast( this ), "ds", dataSource );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void closeConnection(Connection conn) throws SQLException {
|
||||||
|
Connection originalConnection = connectionSpyMap.get( conn );
|
||||||
|
|
||||||
|
super.closeConnection( originalConnection != null ? originalConnection : conn );
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<Connection, Connection> getConnectionSpyMap() {
|
||||||
|
return connectionSpyMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
connectionSpyMap.clear();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
mock-maker-inline
|
|
@ -28,7 +28,7 @@ import org.hibernate.exception.SQLGrammarException;
|
||||||
import org.hibernate.testing.RequiresDialect;
|
import org.hibernate.testing.RequiresDialect;
|
||||||
import org.hibernate.testing.TestForIssue;
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
||||||
import org.hibernate.test.util.jdbc.SQLStatementInterceptor;
|
import org.hibernate.testing.jdbc.SQLStatementInterceptor;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ import org.hibernate.jpa.QueryHints;
|
||||||
|
|
||||||
import org.hibernate.testing.TestForIssue;
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
||||||
import org.hibernate.test.util.jdbc.SQLStatementInterceptor;
|
import org.hibernate.testing.jdbc.SQLStatementInterceptor;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
||||||
|
|
|
@ -19,7 +19,7 @@ import org.hibernate.testing.RequiresDialectFeature;
|
||||||
import org.hibernate.testing.SkipForDialect;
|
import org.hibernate.testing.SkipForDialect;
|
||||||
import org.hibernate.testing.TestForIssue;
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
||||||
import org.hibernate.test.util.jdbc.SQLStatementInterceptor;
|
import org.hibernate.testing.jdbc.SQLStatementInterceptor;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
|
@ -11,7 +11,7 @@ import org.hibernate.dialect.SQLServer2005Dialect;
|
||||||
|
|
||||||
import org.hibernate.testing.RequiresDialect;
|
import org.hibernate.testing.RequiresDialect;
|
||||||
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
||||||
import org.hibernate.test.util.jdbc.SQLStatementInterceptor;
|
import org.hibernate.testing.jdbc.SQLStatementInterceptor;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ import org.hibernate.cfg.Environment;
|
||||||
import org.hibernate.dialect.H2Dialect;
|
import org.hibernate.dialect.H2Dialect;
|
||||||
|
|
||||||
import org.hibernate.testing.RequiresDialect;
|
import org.hibernate.testing.RequiresDialect;
|
||||||
import org.hibernate.test.util.ReflectionUtil;
|
import org.hibernate.testing.util.ReflectionUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Vlad Mihalcea
|
* @author Vlad Mihalcea
|
||||||
|
|
|
@ -14,7 +14,7 @@ import org.hibernate.dialect.MariaDBDialect;
|
||||||
import org.hibernate.dialect.MySQLDialect;
|
import org.hibernate.dialect.MySQLDialect;
|
||||||
|
|
||||||
import org.hibernate.testing.RequiresDialect;
|
import org.hibernate.testing.RequiresDialect;
|
||||||
import org.hibernate.test.util.ReflectionUtil;
|
import org.hibernate.testing.util.ReflectionUtil;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -10,11 +10,10 @@ import javax.sql.DataSource;
|
||||||
|
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.cfg.Environment;
|
import org.hibernate.cfg.Environment;
|
||||||
import org.hibernate.dialect.MySQLDialect;
|
|
||||||
import org.hibernate.dialect.Oracle8iDialect;
|
import org.hibernate.dialect.Oracle8iDialect;
|
||||||
|
|
||||||
import org.hibernate.testing.RequiresDialect;
|
import org.hibernate.testing.RequiresDialect;
|
||||||
import org.hibernate.test.util.ReflectionUtil;
|
import org.hibernate.testing.util.ReflectionUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Vlad Mihalcea
|
* @author Vlad Mihalcea
|
||||||
|
|
|
@ -10,11 +10,10 @@ import javax.sql.DataSource;
|
||||||
|
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.cfg.Environment;
|
import org.hibernate.cfg.Environment;
|
||||||
import org.hibernate.dialect.H2Dialect;
|
|
||||||
import org.hibernate.dialect.PostgreSQL81Dialect;
|
import org.hibernate.dialect.PostgreSQL81Dialect;
|
||||||
|
|
||||||
import org.hibernate.testing.RequiresDialect;
|
import org.hibernate.testing.RequiresDialect;
|
||||||
import org.hibernate.test.util.ReflectionUtil;
|
import org.hibernate.testing.util.ReflectionUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Vlad Mihalcea
|
* @author Vlad Mihalcea
|
||||||
|
|
|
@ -10,11 +10,10 @@ import javax.sql.DataSource;
|
||||||
|
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.cfg.Environment;
|
import org.hibernate.cfg.Environment;
|
||||||
import org.hibernate.dialect.PostgreSQL81Dialect;
|
|
||||||
import org.hibernate.dialect.SQLServerDialect;
|
import org.hibernate.dialect.SQLServerDialect;
|
||||||
|
|
||||||
import org.hibernate.testing.RequiresDialect;
|
import org.hibernate.testing.RequiresDialect;
|
||||||
import org.hibernate.test.util.ReflectionUtil;
|
import org.hibernate.testing.util.ReflectionUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Vlad Mihalcea
|
* @author Vlad Mihalcea
|
||||||
|
|
|
@ -1,159 +0,0 @@
|
||||||
package org.hibernate.test.util;
|
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Vlad Mihalcea
|
|
||||||
*/
|
|
||||||
public class ReflectionUtil {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a field from a given class
|
|
||||||
* @param clazz clazz
|
|
||||||
* @param name field name
|
|
||||||
* @return field object
|
|
||||||
*/
|
|
||||||
public static Field getField(Class clazz, String name) {
|
|
||||||
try {
|
|
||||||
Field field = clazz.getDeclaredField( name );
|
|
||||||
field.setAccessible( true );
|
|
||||||
return field;
|
|
||||||
}
|
|
||||||
catch ( NoSuchFieldException e ) {
|
|
||||||
throw new IllegalArgumentException( "Class " + clazz + " does not contain a " + name + " field", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a field value from a given object
|
|
||||||
* @param target Object whose field is being read
|
|
||||||
* @param name field name
|
|
||||||
* @return field object
|
|
||||||
*/
|
|
||||||
public static <T> T getFieldValue(Object target, String name) {
|
|
||||||
try {
|
|
||||||
Field field = target.getClass().getDeclaredField( name );
|
|
||||||
field.setAccessible( true );
|
|
||||||
return (T) field.get( target );
|
|
||||||
}
|
|
||||||
catch ( NoSuchFieldException e ) {
|
|
||||||
throw new IllegalArgumentException( "Class " + target.getClass() + " does not contain a " + name + " field", e);
|
|
||||||
}
|
|
||||||
catch ( IllegalAccessException e ) {
|
|
||||||
throw new IllegalArgumentException( "Cannot set field " + name, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set target Object field to a certain value
|
|
||||||
* @param target Object whose field is being set
|
|
||||||
* @param field Object field to set
|
|
||||||
* @param value the new value for the given field
|
|
||||||
*/
|
|
||||||
public static void setField(Object target, Field field, Object value) {
|
|
||||||
try {
|
|
||||||
field.set( target, value );
|
|
||||||
}
|
|
||||||
catch ( IllegalAccessException e ) {
|
|
||||||
throw new IllegalArgumentException("Field " + field + " could not be set", e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set target Object field to a certain value
|
|
||||||
* @param target Object whose field is being set
|
|
||||||
* @param fieldName Object field naem to set
|
|
||||||
* @param value the new value for the given field
|
|
||||||
*/
|
|
||||||
public static void setField(Object target, String fieldName, Object value) {
|
|
||||||
try {
|
|
||||||
Field field = getField(target.getClass(), fieldName);
|
|
||||||
field.set( target, value );
|
|
||||||
}
|
|
||||||
catch ( IllegalAccessException e ) {
|
|
||||||
throw new IllegalArgumentException("Field " + fieldName + " could not be set", e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* New target Object instance using the given arguments
|
|
||||||
* @param constructorSupplier constructor supplier
|
|
||||||
* @param args Constructor arguments
|
|
||||||
* @return new Object instance
|
|
||||||
*/
|
|
||||||
public static <T> T newInstance(Supplier<Constructor<T>> constructorSupplier, Object... args) {
|
|
||||||
try {
|
|
||||||
Constructor constructor = constructorSupplier.get();
|
|
||||||
constructor.setAccessible( true );
|
|
||||||
return (T) constructor.newInstance( args );
|
|
||||||
}
|
|
||||||
catch ( IllegalAccessException | InstantiationException | InvocationTargetException e ) {
|
|
||||||
throw new IllegalArgumentException("Constructor could not be called", e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* New target Object instance using the given Class name
|
|
||||||
* @param className class name
|
|
||||||
* @return new Object instance
|
|
||||||
*/
|
|
||||||
public static <T> T newInstance(String className) {
|
|
||||||
try {
|
|
||||||
return (T) Class.forName( className ).newInstance();
|
|
||||||
}
|
|
||||||
catch ( ClassNotFoundException | IllegalAccessException | InstantiationException e ) {
|
|
||||||
throw new IllegalArgumentException("Constructor could not be called", e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get setter method
|
|
||||||
*
|
|
||||||
* @param target target object
|
|
||||||
* @param property property
|
|
||||||
* @param parameterType setter parameter type
|
|
||||||
* @return setter method
|
|
||||||
*/
|
|
||||||
public static Method getSetter(Object target, String property, Class<?> parameterType) {
|
|
||||||
String setterMethodName = "set" + property.substring(0, 1).toUpperCase() + property.substring(1);
|
|
||||||
Method setter = getMethod(target, setterMethodName, parameterType);
|
|
||||||
setter.setAccessible(true);
|
|
||||||
return setter;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get target method
|
|
||||||
*
|
|
||||||
* @param target target object
|
|
||||||
* @param methodName method name
|
|
||||||
* @param parameterTypes method parameter types
|
|
||||||
* @return return value
|
|
||||||
*/
|
|
||||||
public static Method getMethod(Object target, String methodName, Class... parameterTypes) {
|
|
||||||
try {
|
|
||||||
return target.getClass().getMethod(methodName, parameterTypes);
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
throw new IllegalArgumentException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invoke setter method with the given parameter
|
|
||||||
*
|
|
||||||
* @param target target object
|
|
||||||
* @param property property
|
|
||||||
* @param parameter setter parameter
|
|
||||||
*/
|
|
||||||
public static void setProperty(Object target, String property, Object parameter) {
|
|
||||||
Method setter = getSetter( target, property, parameter.getClass());
|
|
||||||
try {
|
|
||||||
setter.invoke(target, parameter);
|
|
||||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
|
||||||
throw new IllegalArgumentException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -4,7 +4,7 @@
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
* 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>.
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
*/
|
*/
|
||||||
package org.hibernate.test.util.jdbc;
|
package org.hibernate.testing.jdbc;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
|
|
@ -0,0 +1,221 @@
|
||||||
|
/*
|
||||||
|
* 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.testing.util;
|
||||||
|
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Vlad Mihalcea
|
||||||
|
*/
|
||||||
|
public class ReflectionUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a field from a given class
|
||||||
|
*
|
||||||
|
* @param clazz clazz
|
||||||
|
* @param name field name
|
||||||
|
*
|
||||||
|
* @return field object
|
||||||
|
*/
|
||||||
|
public static Field getField(Class clazz, String name) {
|
||||||
|
try {
|
||||||
|
Field field = clazz.getDeclaredField( name );
|
||||||
|
field.setAccessible( true );
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
catch (NoSuchFieldException e) {
|
||||||
|
Class superClass = clazz.getSuperclass();
|
||||||
|
if ( !clazz.equals( superClass ) ) {
|
||||||
|
return getField( superClass, name );
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException( "Class " + clazz + " does not contain a " + name + " field", e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a field value from a given object
|
||||||
|
*
|
||||||
|
* @param target Object whose field is being read
|
||||||
|
* @param name field name
|
||||||
|
*
|
||||||
|
* @return field object
|
||||||
|
*/
|
||||||
|
public static <T> T getFieldValue(Object target, String name) {
|
||||||
|
try {
|
||||||
|
Field field = target.getClass().getDeclaredField( name );
|
||||||
|
field.setAccessible( true );
|
||||||
|
return (T) field.get( target );
|
||||||
|
}
|
||||||
|
catch (NoSuchFieldException e) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Class " + target.getClass() + " does not contain a " + name + " field",
|
||||||
|
e
|
||||||
|
);
|
||||||
|
}
|
||||||
|
catch (IllegalAccessException e) {
|
||||||
|
throw new IllegalArgumentException( "Cannot set field " + name, e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a field value from a given class
|
||||||
|
*
|
||||||
|
* @param target Class whose field is being read
|
||||||
|
* @param name field name
|
||||||
|
*
|
||||||
|
* @return field value
|
||||||
|
*/
|
||||||
|
public static <T> T getStaticFieldValue(Class<?> target, String name) {
|
||||||
|
try {
|
||||||
|
Field field = getField( target, name );
|
||||||
|
return (T) field.get( null );
|
||||||
|
}
|
||||||
|
catch (IllegalAccessException e) {
|
||||||
|
throw new IllegalArgumentException( "Cannot set field " + name, e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set target Object field to a certain value
|
||||||
|
*
|
||||||
|
* @param target Object whose field is being set
|
||||||
|
* @param field Object field to set
|
||||||
|
* @param value the new value for the given field
|
||||||
|
*/
|
||||||
|
public static void setField(Object target, Field field, Object value) {
|
||||||
|
try {
|
||||||
|
field.set( target, value );
|
||||||
|
}
|
||||||
|
catch (IllegalAccessException e) {
|
||||||
|
throw new IllegalArgumentException( "Field " + field + " could not be set", e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set target Object field to a certain value
|
||||||
|
*
|
||||||
|
* @param target Object whose field is being set
|
||||||
|
* @param fieldName Object field naem to set
|
||||||
|
* @param value the new value for the given field
|
||||||
|
*/
|
||||||
|
public static void setField(Object target, String fieldName, Object value) {
|
||||||
|
try {
|
||||||
|
Field field = getField( target.getClass(), fieldName );
|
||||||
|
field.set( target, value );
|
||||||
|
}
|
||||||
|
catch (IllegalAccessException e) {
|
||||||
|
throw new IllegalArgumentException( "Field " + fieldName + " could not be set", e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set target Class field to a certain value
|
||||||
|
*
|
||||||
|
* @param target Class whose field is being set
|
||||||
|
* @param fieldName Class field name to set
|
||||||
|
* @param value the new value for the given field
|
||||||
|
*/
|
||||||
|
public static void setStaticField(Class<?> target, String fieldName, Object value) {
|
||||||
|
try {
|
||||||
|
Field field = getField( target, fieldName );
|
||||||
|
field.set( null, value );
|
||||||
|
}
|
||||||
|
catch (IllegalAccessException e) {
|
||||||
|
throw new IllegalArgumentException( "Field " + fieldName + " could not be set", e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* New target Object instance using the given arguments
|
||||||
|
*
|
||||||
|
* @param constructorSupplier constructor supplier
|
||||||
|
* @param args Constructor arguments
|
||||||
|
*
|
||||||
|
* @return new Object instance
|
||||||
|
*/
|
||||||
|
public static <T> T newInstance(Supplier<Constructor<T>> constructorSupplier, Object... args) {
|
||||||
|
try {
|
||||||
|
Constructor constructor = constructorSupplier.get();
|
||||||
|
constructor.setAccessible( true );
|
||||||
|
return (T) constructor.newInstance( args );
|
||||||
|
}
|
||||||
|
catch (IllegalAccessException | InstantiationException | InvocationTargetException e) {
|
||||||
|
throw new IllegalArgumentException( "Constructor could not be called", e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* New target Object instance using the given Class name
|
||||||
|
*
|
||||||
|
* @param className class name
|
||||||
|
*
|
||||||
|
* @return new Object instance
|
||||||
|
*/
|
||||||
|
public static <T> T newInstance(String className) {
|
||||||
|
try {
|
||||||
|
return (T) Class.forName( className ).newInstance();
|
||||||
|
}
|
||||||
|
catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {
|
||||||
|
throw new IllegalArgumentException( "Constructor could not be called", e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get setter method
|
||||||
|
*
|
||||||
|
* @param target target object
|
||||||
|
* @param property property
|
||||||
|
* @param parameterType setter parameter type
|
||||||
|
*
|
||||||
|
* @return setter method
|
||||||
|
*/
|
||||||
|
public static Method getSetter(Object target, String property, Class<?> parameterType) {
|
||||||
|
String setterMethodName = "set" + property.substring( 0, 1 ).toUpperCase() + property.substring( 1 );
|
||||||
|
Method setter = getMethod( target, setterMethodName, parameterType );
|
||||||
|
setter.setAccessible( true );
|
||||||
|
return setter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get target method
|
||||||
|
*
|
||||||
|
* @param target target object
|
||||||
|
* @param methodName method name
|
||||||
|
* @param parameterTypes method parameter types
|
||||||
|
*
|
||||||
|
* @return return value
|
||||||
|
*/
|
||||||
|
public static Method getMethod(Object target, String methodName, Class... parameterTypes) {
|
||||||
|
try {
|
||||||
|
return target.getClass().getMethod( methodName, parameterTypes );
|
||||||
|
}
|
||||||
|
catch (NoSuchMethodException e) {
|
||||||
|
throw new IllegalArgumentException( e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoke setter method with the given parameter
|
||||||
|
*
|
||||||
|
* @param target target object
|
||||||
|
* @param property property
|
||||||
|
* @param parameter setter parameter
|
||||||
|
*/
|
||||||
|
public static void setProperty(Object target, String property, Object parameter) {
|
||||||
|
Method setter = getSetter( target, property, parameter.getClass() );
|
||||||
|
try {
|
||||||
|
setter.invoke( target, parameter );
|
||||||
|
}
|
||||||
|
catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
|
throw new IllegalArgumentException( e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue