diff --git a/core/testsuite/src/test/hibernate/com/blazebit/persistence/testsuite/Issue545Test.java b/core/testsuite/src/test/hibernate/com/blazebit/persistence/testsuite/Issue545Test.java new file mode 100644 index 0000000000..725c63c124 --- /dev/null +++ b/core/testsuite/src/test/hibernate/com/blazebit/persistence/testsuite/Issue545Test.java @@ -0,0 +1,158 @@ +/* + * Copyright 2014 - 2018 Blazebit. + * + * 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.blazebit.persistence.testsuite; + +import com.blazebit.persistence.testsuite.tx.TxVoidWork; +import org.hibernate.HibernateException; +import org.hibernate.annotations.Formula; +import org.hibernate.annotations.Type; +import org.hibernate.annotations.TypeDef; +import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.hibernate.usertype.UserType; +import org.junit.Before; +import org.junit.Test; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EntityManager; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import java.io.Serializable; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; + +import static org.junit.Assert.assertNotNull; + +/** + * @author Jan-Willem Gmelig Meyling + * @since 1.3.0 + */ +public class Issue545Test extends AbstractCoreTest { + + @Override + protected Class[] getEntityClasses() { + return new Class[] { EntityWithCustomType.class }; + } + + @Before + public void setUp() throws Exception { + transactional(new TxVoidWork() { + @Override + public void work(EntityManager em) { + EntityWithCustomType entityWithCustomType = new EntityWithCustomType(); + entityWithCustomType.customValue = "custom"; + em.persist(entityWithCustomType); + em.flush(); + em.clear(); + } + }); + } + + @Test + public void queryEntityWithCustomTypeTest() { + transactional(new TxVoidWork() { + @Override + public void work(EntityManager em) { + EntityWithCustomType singleResult = cbf.create(em, EntityWithCustomType.class) + .where("transformedCustomValue").eq("CUSTOM") + .getSingleResult(); + + assertNotNull(singleResult); + } + }); + } + + @Entity + @TypeDef(name = "CustomType", typeClass = CustomType.class) + public static class EntityWithCustomType { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + @Column(name = "custom_value") + private String customValue; + + @Formula("UPPER(custom_value)") + @Type(type = "CustomType") + private String transformedCustomValue; + + } + + public static class CustomType implements UserType { + + @Override + public int[] sqlTypes() { + return new int[] { Types.VARCHAR }; + } + + @Override + public Class returnedClass() { + return String.class; + } + + @Override + public boolean equals(Object x, Object y) throws HibernateException { + return x.equals(y); + } + + @Override + public int hashCode(Object x) throws HibernateException { + return x.hashCode(); + } + + @Override + public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws HibernateException, SQLException { + return rs.getString(names[0]); + } + + @Override + public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session) throws HibernateException, SQLException { + st.setString(index, value.toString()); + + } + + @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 (Serializable) value; + } + + @Override + public Object assemble(Serializable cached, Object owner) throws HibernateException { + return cached; + } + + @Override + public Object replace(Object original, Object target, Object owner) throws HibernateException { + return original; + } + } + +} diff --git a/integration/hibernate-base/src/main/java/com/blazebit/persistence/integration/hibernate/base/HibernateJpaProvider.java b/integration/hibernate-base/src/main/java/com/blazebit/persistence/integration/hibernate/base/HibernateJpaProvider.java index f34413df40..33e38efc78 100644 --- a/integration/hibernate-base/src/main/java/com/blazebit/persistence/integration/hibernate/base/HibernateJpaProvider.java +++ b/integration/hibernate-base/src/main/java/com/blazebit/persistence/integration/hibernate/base/HibernateJpaProvider.java @@ -59,6 +59,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.logging.Logger; /** * @@ -68,6 +69,8 @@ public class HibernateJpaProvider implements JpaProvider { private static final Method GET_TYPE_NAME; + private static final Logger LOG = Logger.getLogger(HibernateJpaProvider.class.getName()); + protected final DB db; protected final Map entityPersisters; protected final Map collectionPersisters; @@ -568,21 +571,23 @@ public String[] getColumnTypes(EntityType entityType, String attributeName) { if (isFormula || isSubselect) { Type propertyType = entityPersister.getPropertyType(attributeName); - long length; - int precision; - int scale; - try { - if (propertyType instanceof org.hibernate.type.EntityType) { - propertyType = ((org.hibernate.type.EntityType) propertyType).getIdentifierOrUniqueKeyType(sfi); - } + if (propertyType instanceof org.hibernate.type.EntityType) { + propertyType = ((org.hibernate.type.EntityType) propertyType).getIdentifierOrUniqueKeyType(sfi); + } + + long length = Column.DEFAULT_LENGTH; + int precision = Column.DEFAULT_PRECISION; + int scale = Column.DEFAULT_SCALE; + + try { Method m = Type.class.getMethod("dictatedSizes", Mapping.class); Object size = ((Object[]) m.invoke(propertyType, sfi))[0]; length = (long) size.getClass().getMethod("getLength").invoke(size); precision = (int) size.getClass().getMethod("getPrecision").invoke(size); scale = (int) size.getClass().getMethod("getScale").invoke(size); } catch (Exception ex) { - throw new RuntimeException("Could not determine the column type of the attribute: " + attributeName + " of the entity: " + entityType.getName()); + LOG.fine("Could not determine the column type of the attribute: " + attributeName + " of the entity: " + entityType.getName()); } return new String[] {