Custom UserType is not really a singleton

The issue is that I want to inject different Spring beans into each MyType instance: a1 gets one value, but a2/b1/b2 all get different values. These are all injected after the EntityManagerFactory is complete and Spring is initializing the rest of the application beans, by crawling the EMF/EntityPersister.

If MyTypes are singletons per field, I can easily find them all and inject whatever I want. But EntityPersister.getPropertyType(“a1”).getUserType() returns only one of the instances created for a given field. I don’t see a way to find all of them, or to set the configuration only once for the MyType associated with a given field.

Apparently the problem is that SimpleValue.getType always re-creates the type; it’s own type variable isn’t being assigned, so every call to getType() ends up calling TypeResolver.heuristicType.

Here are the first few stack traces on the MyType constructor; these are all for the same field:

	at java.lang.Class.newInstance(Class.java:442)
	at org.hibernate.type.TypeFactory.custom(TypeFactory.java:177)
	at org.hibernate.type.TypeFactory.byClass(TypeFactory.java:78)
	at org.hibernate.type.TypeResolver.heuristicType(TypeResolver.java:126)
	at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:484)
	at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:466)
	at org.hibernate.mapping.Property.isValid(Property.java:227)
	at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:624)
	at org.hibernate.mapping.RootClass.validate(RootClass.java:267)
	at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:354)
	at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:465)
	at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1259)

Then again:

	at java.lang.Class.newInstance(Class.java:442)
	at org.hibernate.type.TypeFactory.custom(TypeFactory.java:177)
	at org.hibernate.type.TypeFactory.byClass(TypeFactory.java:78)
	at org.hibernate.type.TypeResolver.heuristicType(TypeResolver.java:126)
	at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:484)
	at org.hibernate.mapping.Property.getType(Property.java:70)
	at org.hibernate.event.service.internal.EventListenerRegistryImpl.prepare(EventListenerRegistryImpl.java:152)
	at org.hibernate.boot.internal.MetadataImpl.initSessionFactory(MetadataImpl.java:379)
	at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:213)
	at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:469)
	at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1259)

Again:

	at java.lang.Class.newInstance(Class.java:442)
	at org.hibernate.type.TypeFactory.custom(TypeFactory.java:177)
	at org.hibernate.type.TypeFactory.byClass(TypeFactory.java:78)
	at org.hibernate.type.TypeResolver.heuristicType(TypeResolver.java:126)
	at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:484)
	at org.hibernate.tuple.PropertyFactory.buildEntityBasedAttribute(PropertyFactory.java:158)
	at org.hibernate.tuple.entity.EntityMetamodel.<init>(EntityMetamodel.java:224)
	at org.hibernate.persister.entity.AbstractEntityPersister.<init>(AbstractEntityPersister.java:604)
	at org.hibernate.persister.entity.SingleTableEntityPersister.<init>(SingleTableEntityPersister.java:125)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister(PersisterFactoryImpl.java:96)
	at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister(PersisterFactoryImpl.java:77)
	at org.hibernate.metamodel.internal.MetamodelImpl.initialize(MetamodelImpl.java:181)
	at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:301)
	at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:469)
	at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1259)

There’s a few more but you get the idea.