Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
HHH-14408 Test that user type provided by integrator is properly regi…
…stered
- Loading branch information
Showing
5 changed files
with
305 additions
and
1 deletion.
There are no files selected for viewing
120 changes: 120 additions & 0 deletions
120
hibernate-core/src/test/java/org/hibernate/test/usertype/IntegratorProvidedUserTypeTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
/* | ||
* 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.usertype; | ||
|
||
import java.io.ByteArrayOutputStream; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.io.Serializable; | ||
import java.net.URL; | ||
import java.util.Enumeration; | ||
import javax.persistence.Entity; | ||
import javax.persistence.Id; | ||
|
||
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder; | ||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder; | ||
import org.hibernate.internal.util.ConfigHelper; | ||
import org.hibernate.type.CustomType; | ||
import org.hibernate.type.Type; | ||
|
||
import org.hibernate.testing.TestForIssue; | ||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; | ||
import org.junit.Assert; | ||
import org.junit.Test; | ||
|
||
/** | ||
* @author Christian Beikov | ||
*/ | ||
public class IntegratorProvidedUserTypeTest extends BaseCoreFunctionalTestCase { | ||
|
||
@Override | ||
protected Class<?>[] getAnnotatedClasses() { | ||
return new Class[] { | ||
StringWrapperTestEntity.class | ||
}; | ||
} | ||
|
||
protected void prepareBootstrapRegistryBuilder(BootstrapServiceRegistryBuilder builder) { | ||
builder.applyClassLoader( new TestClassLoader() ); | ||
} | ||
|
||
@Test | ||
@TestForIssue( jiraKey = "HHH-14408" ) | ||
public void test() { | ||
Type type = sessionFactory().getMetamodel().entityPersister( StringWrapperTestEntity.class ) | ||
.getPropertyType( "stringWrapper" ); | ||
Assert.assertTrue( "Type was initialized too early i.e. before integrators were run", type instanceof CustomType ); | ||
} | ||
|
||
@Entity | ||
public static class StringWrapperTestEntity implements Serializable { | ||
@Id | ||
private Integer id; | ||
private StringWrapper stringWrapper; | ||
} | ||
|
||
private static class TestClassLoader extends ClassLoader { | ||
|
||
/** | ||
* testStoppableClassLoaderService() needs a custom JDK service implementation. Rather than using a real one | ||
* on the test classpath, force it in here. | ||
*/ | ||
@Override | ||
protected Enumeration<URL> findResources(String name) throws IOException { | ||
if (name.equals( "META-INF/services/org.hibernate.integrator.spi.Integrator" )) { | ||
final URL serviceUrl = ConfigHelper.findAsResource( | ||
"org/hibernate/test/service/org.hibernate.integrator.spi.Integrator" ); | ||
return new Enumeration<URL>() { | ||
boolean hasMore = true; | ||
|
||
@Override | ||
public boolean hasMoreElements() { | ||
return hasMore; | ||
} | ||
|
||
@Override | ||
public URL nextElement() { | ||
hasMore = false; | ||
return serviceUrl; | ||
} | ||
}; | ||
} | ||
else { | ||
return java.util.Collections.enumeration( java.util.Collections.<URL>emptyList() ); | ||
} | ||
} | ||
|
||
/** | ||
* Reloading class from binary file. | ||
* | ||
* @param originalClass Original class. | ||
* @throws IOException . | ||
*/ | ||
public void overrideClass(final Class<?> originalClass) throws IOException { | ||
String originalPath = "/" + originalClass.getName().replaceAll("\\.", "/") + ".class"; | ||
InputStream inputStream = originalClass.getResourceAsStream( originalPath); | ||
Assert.assertNotNull(inputStream); | ||
try { | ||
byte[] data = toByteArray( inputStream ); | ||
defineClass(originalClass.getName(), data, 0, data.length); | ||
} finally { | ||
inputStream.close(); | ||
} | ||
} | ||
|
||
private byte[] toByteArray(InputStream inputStream) throws IOException { | ||
ByteArrayOutputStream out = new ByteArrayOutputStream(); | ||
int read; | ||
byte[] slice = new byte[2000]; | ||
while ( (read = inputStream.read(slice, 0, slice.length) ) != -1) { | ||
out.write( slice, 0, read ); | ||
} | ||
out.flush(); | ||
return out.toByteArray(); | ||
} | ||
} | ||
} |
38 changes: 38 additions & 0 deletions
38
hibernate-core/src/test/java/org/hibernate/test/usertype/StringWrapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package org.hibernate.test.usertype; | ||
|
||
import java.io.Serializable; | ||
|
||
/** | ||
* @author Christian Beikov | ||
*/ | ||
public class StringWrapper implements Serializable { | ||
|
||
private final String value; | ||
|
||
public StringWrapper(String value) { | ||
this.value = value; | ||
} | ||
|
||
public String getValue() { | ||
return value; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if ( this == o ) { | ||
return true; | ||
} | ||
if ( o == null || getClass() != o.getClass() ) { | ||
return false; | ||
} | ||
|
||
StringWrapper that = (StringWrapper) o; | ||
|
||
return value.equals( that.value ); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return value.hashCode(); | ||
} | ||
} |
112 changes: 112 additions & 0 deletions
112
hibernate-core/src/test/java/org/hibernate/test/usertype/StringWrapperUserType.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
package org.hibernate.test.usertype; | ||
|
||
import java.io.Serializable; | ||
import java.sql.PreparedStatement; | ||
import java.sql.ResultSet; | ||
import java.sql.SQLException; | ||
import java.sql.Types; | ||
import java.util.Objects; | ||
|
||
import org.hibernate.HibernateException; | ||
import org.hibernate.engine.spi.SharedSessionContractImplementor; | ||
import org.hibernate.type.StringType; | ||
import org.hibernate.usertype.UserType; | ||
|
||
import org.jboss.logging.Logger; | ||
|
||
/** | ||
* @author Christian Beikov | ||
*/ | ||
public class StringWrapperUserType implements UserType { | ||
|
||
public static final StringWrapperUserType INSTANCE = new StringWrapperUserType(); | ||
|
||
private static final Logger log = Logger.getLogger( StringWrapperUserType.class ); | ||
|
||
@Override | ||
public int[] sqlTypes() { | ||
return new int[] {StringType.INSTANCE.sqlType()}; | ||
} | ||
|
||
@Override | ||
public Class returnedClass() { | ||
return StringWrapper.class; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object x, Object y) | ||
throws HibernateException { | ||
return Objects.equals( x, y ); | ||
} | ||
|
||
@Override | ||
public int hashCode(Object x) | ||
throws HibernateException { | ||
return Objects.hashCode( x ); | ||
} | ||
|
||
@Override | ||
public Object nullSafeGet( | ||
ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) | ||
throws HibernateException, SQLException { | ||
String columnName = names[0]; | ||
String columnValue = (String) rs.getObject( columnName ); | ||
log.debugv("Result set column {0} value is {1}", columnName, columnValue); | ||
return columnValue == null ? null : | ||
fromString( columnValue ); | ||
} | ||
|
||
@Override | ||
public void nullSafeSet( | ||
PreparedStatement st, Object value, int index, SharedSessionContractImplementor session) | ||
throws HibernateException, SQLException { | ||
if ( value == null ) { | ||
log.debugv("Binding null to parameter {0} ",index); | ||
st.setNull( index, Types.VARCHAR ); | ||
} | ||
else { | ||
String stringValue = toString( (StringWrapper) value ); | ||
log.debugv("Binding {0} to parameter {1} ", stringValue, index); | ||
st.setString( index, stringValue ); | ||
} | ||
} | ||
public String toString(StringWrapper value) { | ||
return value.getValue(); | ||
} | ||
|
||
public StringWrapper fromString(String string) { | ||
if ( string == null || string.isEmpty() ) { | ||
return null; | ||
} | ||
return new StringWrapper( string ); | ||
} | ||
|
||
@Override | ||
public Object deepCopy(Object value) | ||
throws HibernateException { | ||
return value; | ||
} | ||
|
||
@Override | ||
public boolean isMutable() { | ||
return false; | ||
} | ||
|
||
@Override | ||
public Serializable disassemble(Object value) | ||
throws HibernateException { | ||
return (StringWrapper) deepCopy( value ); | ||
} | ||
|
||
@Override | ||
public Object assemble(Serializable cached, Object owner) | ||
throws HibernateException { | ||
return deepCopy( cached ); | ||
} | ||
|
||
@Override | ||
public Object replace(Object original, Object target, Object owner) | ||
throws HibernateException { | ||
return deepCopy( original ); | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
...rnate-core/src/test/java/org/hibernate/test/usertype/StringWrapperUserTypeIntegrator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/* | ||
* 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.usertype; | ||
|
||
import org.hibernate.boot.Metadata; | ||
import org.hibernate.boot.spi.MetadataImplementor; | ||
import org.hibernate.engine.spi.SessionFactoryImplementor; | ||
import org.hibernate.integrator.spi.Integrator; | ||
import org.hibernate.service.spi.SessionFactoryServiceRegistry; | ||
|
||
/** | ||
* @author Christian Beikov | ||
*/ | ||
public class StringWrapperUserTypeIntegrator implements Integrator { | ||
@Override | ||
public void integrate( | ||
Metadata metadata, | ||
SessionFactoryImplementor sessionFactory, | ||
SessionFactoryServiceRegistry serviceRegistry) { | ||
MetadataImplementor mi = (MetadataImplementor) metadata; | ||
mi.getTypeResolver().registerTypeOverride( StringWrapperUserType.INSTANCE, new String[] { StringWrapperUserType.INSTANCE.returnedClass().getName()}); | ||
} | ||
|
||
@Override | ||
public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) { | ||
|
||
} | ||
|
||
} |
3 changes: 2 additions & 1 deletion
3
...ore/src/test/resources/org/hibernate/test/service/org.hibernate.integrator.spi.Integrator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
org.hibernate.test.service.TestIntegrator | ||
org.hibernate.test.service.TestIntegrator | ||
org.hibernate.test.usertype.StringWrapperUserTypeIntegrator |