Hi,
I was trying to use Component.addTuplizer method in class
org.hibernate.mapping.Component but at runtime hibernate failed to pickup my
custom tuplizer.
Here is a code snippet I was running:
org.hibernate.cfg.Configuration hiberConfig = context.getHiberConfiguration();
Iterator iter = hiberConfig.getClassMappings();
while(iter.hasNext())
{
PersistentClass cls = (PersistentClass)iter.next();
String entityName = cls.getEntityName();
logger.info("Found entity mapping: " + entityName);
map.put(entityName, entityName);
try
{
CdlEntityId clsId = CdlDictionary.getInstance().getClassId(entityName);
if(clsId != null)
{
cls.addTuplizer(EntityMode.MAP, CdlCustomEntityMapTuplizer.class.getName());
Iterator propIter = cls.getPropertyIterator();
while(propIter.hasNext())
{
registerComponentTuplizers ((Property)propIter.next());
}
}
}
catch(CdlException cdle){}
}
private void
registerComponentTuplizers (Property property)
{
if (property.getType().isComponentType())
{
Component component = (Component) property.getValue();
component.addTuplizer (EntityMode.MAP,
CdlCustomComponentTuplizer.class.getName());
Iterator propIter = component.getPropertyIterator();
while(propIter.hasNext())
{
registerComponentTuplizers ((Property)propIter.next());
}
}
}
There were no exceptions but my custom tuplizer was not
constructed, instead I was getting default one for Map mode. When I looked in
code in Component class (I extracted relavent code from Comonent class) I
noticed that actual mapping resides in ComponentType (type variable) which gets
initialized when getType() is called and is cached. This addition of caching I
think broke addTuplizer() method because type will not get recreated again and
you are stuck with the mappings that were in tuplizerImpls map variable at the
time getType() is called.
public class Component extends
SimpleValue implements MetaAttributable {
private java.util.Map tuplizerImpls;
private Type type;
public Type getType() throws MappingException {
// added this caching as I noticed that getType() is being called multiple
times...
if ( type == null ) {
type = buildType();
}
return type;
}
private Type buildType() {
// TODO : temporary initial step towards HHH-1907
ComponentMetamodel metamodel = new ComponentMetamodel( this );
if ( isEmbedded() ) {
return new EmbeddedComponentType( metamodel );
}
else {
return new ComponentType( metamodel );
}
}
public
void addTuplizer(EntityMode entityMode, String implClassName) {
if ( tuplizerImpls == null ) {
tuplizerImpls = new HashMap();
}
tuplizerImpls.put( entityMode, implClassName );
}
public String getTuplizerImplClassName(EntityMode mode) {
// todo : remove this once ComponentMetamodel is complete and merged
if ( tuplizerImpls == null ) {
return null;
}
return ( String ) tuplizerImpls.get( mode );
}
public Map getTuplizerMap() {
if ( tuplizerImpls == null ) {
return null;
}
return java.util.Collections.unmodifiableMap( tuplizerImpls );
}
}
When can this bug get fixed ? Please let me know.
Best regards,