0

I am developing a python script to parse the xml definition of a Java class in hibernate but I'm having an strange case when I am generating the composite-id of a class. This is the particular case of a composite-id that I'm using to run tests:

<hibernate-mapping>
    <class name="es.alejandroat99.entity.Customer" table="CUSTOMER">
        <composite-id name="id" class="es.alejandroat99.entity.CustomerId">
            <key-property name="phone" type="java.lang.String">
                <column name="PHONE"/> 
            </key-property>
            <key-property name="document" type="java.lang.String">
                <column name="DOCUMENT"/>
            </key-property>
        </composite-id>
        <property name="name" type="java.lang.String">
            <column name="NAME"/>
        </property>
    </class>
</hibernate-mapping>

The expected class to be generated should be:

public class Customer {

    private CustomerId id;
    private String name;
    ...
}

public class CustomerId {
    
    private String phone;
    private String document;
    ...
}

But this is the result:

public class Customer {

    private String phone;
    private String document;
    private CustomerId id;
    private String name;
    ...
}

public class CustomerId {

    private String phone;
    private String document;
    ...
}

The attributes inside CustumerId are being duplicated in the Customer class. I have been studying my code and it seems that when the attributes of the CustomerId are stored inside the corresponding object, that same attribute is also stored inside the Customer object in python although I am not doing that insertion. This is my python code for the composite id:

def mapCompositeId(element, jc):
    assert type(element) is ET.Element
    assert type(jc) is JavaClass
    
    # en el composite-id hay que generar la clase id
    name = element.attrib['name']
    classAttrib = element.attrib['class']

    idClass = JavaClass()
    if '.' in classAttrib:
        classPackage = '.'.join(classAttrib.split('.')[:-1])
        idClass.package = classPackage

    idClass.className = classAttrib.split('.')[-1]

    for keyElement in element:
        if keyElement.tag == 'key-property':
            mapProperty(keyElement, idClass)
    
    saveClass(idClass)
    att = JavaAttribute(attributeType=idClass.className, attributeName=name, isKey=True)

    jc.attributes.append(att)

    if idClass.package != jc.package:
        jc.imports.append(classAttrib)

The auxiliar function mapProperty has the following code:

def mapProperty(element, jc):
    assert type(element) is ET.Element
    assert type(jc) is JavaClass
    
    # Obtener los datos del atributo
    attType = element.attrib['type']
    attName = element.attrib['name']

    # Comprobar si se tiene que realizar un import
    if '.' in attType and not attType.startswith('java.lang'):
        jc.imports.append(attType)

    if attType == 'timestamp':
        if 'java.util.Date' not in jc.imports:
            jc.imports.append('java.util.Date')
        attType = 'Date'

    attribute = JavaAttribute(attributeType=attType.split('.')[-1], attributeName=attName)
    jc.attributes.append(attribute)

I have never faced this kind of error in Python and I don't know how to resolve this weird error. If more information is required, this is the repository.

Edit:

Thanks to @buran to help me solve this issue. The problem was caused by the particular way Python treats the default values for function parameters. Python was using the same list for my two objects and my error was solved changing:

 def __init__(self, package=None, className=None, imports=[], attributes=[]):

To this:

def __init__(self, package=None, className=None, imports=None, attributes=None):
Alejandro
  • 21
  • 4
  • 1
    Look at [this line in `JavaClass` class](https://github.com/alejandroat99/hbm2java-python/blob/68c18cc6d27ff1088ad53113258ad34507d91581/hbm2java-python/JavaClass.py#L15) and then check ["Least Astonishment" and the Mutable Default Argument](https://stackoverflow.com/q/1132941/4046632) – buran Apr 13 '22 at 10:03
  • 1
    Additional reading [Common Gotchas - Mutable Default Arguments](https://docs.python-guide.org/writing/gotchas/#mutable-default-arguments) – buran Apr 13 '22 at 10:07
  • Thank you so much @buran , that post is really helpful and my error is solved. – Alejandro Apr 13 '22 at 10:17

0 Answers0