We're updating the issue view to help you get more done. 

AttributeConverter doesn't override built-in type mappings

Description

1 2 3 4 5 6 7 8 9 10 11 12 13 14 @Converter public class MonetaryAmountConverter implements AttributeConverter<MonetaryAmount, String> { @Override public String convertToDatabaseColumn(MonetaryAmount monetaryAmount) { return monetaryAmount.toString(); } @Override public MonetaryAmount convertToEntityAttribute(String s) { return MonetaryAmount.fromString(s); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 public class MonetaryAmount implements Serializable { private final BigDecimal value; private final Currency currency; public MonetaryAmount(BigDecimal value, Currency currency) { this.value = value; this.currency = currency; } public Currency getCurrency() { return currency; } public BigDecimal getValue() { return value; } public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof MonetaryAmount)) return false; final MonetaryAmount monetaryAmount = (MonetaryAmount) o; if (!currency.equals(monetaryAmount.currency)) return false; if (!value.equals(monetaryAmount.value)) return false; return true; } public int hashCode() { int result; result = value.hashCode(); result = 29 * result + currency.hashCode(); return result; } public String toString() { return getValue() + " " + getCurrency(); } public static MonetaryAmount fromString(String s) { String[] split = s.split(" "); return new MonetaryAmount( new BigDecimal(split[0]), Currency.getInstance(split[1]) ); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 Caused by: org.hibernate.HibernateException: Unknown unwrap conversion requested: org.jpwh.model.advanced.MonetaryAmount to java.lang.String at org.hibernate.type.descriptor.java.AbstractTypeDescriptor.unknownUnwrap(AbstractTypeDescriptor.java:103) at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.unwrap(SerializableTypeDescriptor.java:114) at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.unwrap(SerializableTypeDescriptor.java:44) at org.hibernate.type.descriptor.sql.VarcharTypeDescriptor$1.doBind(VarcharTypeDescriptor.java:64) at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:92) at org.hibernate.mapping.SimpleValue$AttributeConverterSqlTypeDescriptorAdapter$1.doBind(SimpleValue.java:490) at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:92) at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:281) at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:276) at org.hibernate.type.AbstractSingleColumnStandardBasicType.nullSafeSet(AbstractSingleColumnStandardBasicType.java:56) at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2778) at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3056) at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3500) at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:88) at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:362) at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:354) at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:275) at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:329) at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52) at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1234) at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:404) at org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorImpl.beforeCompletion(SynchronizationCallbackCoordinatorImpl.java:112) ... 35 more

This works if you remove Serializable from MonetaryAmount.

The problem seems to be JavaTypeDescriptorRegistry#getDescriptor(Class), which gets a match for SerializableTypeDescriptor. If the class isn't Serializable, it passes through to FallbackJavaTypeDescriptor and everything works.

Environment

None

Status

Assignee

Steve Ebersole

Reporter

Christian Bauer

Fix versions

Labels

backPortable

None

Suitable for new contributors

None

Requires Release Note

None

Pull Request

None

backportDecision

None

Affects versions

4.3.0.Beta1

Priority

Major